This project is a backend service built using modern technologies and powerful Node.js libraries. It employs modern architectures such as Dependency Injection and Decorators to ensure clean, maintainable, and scalable code.
- Technologies Used
- Project Structure
- Setup and Installation
- API Documentation
- Logging
- Dependency Injection
- Routing
- Decorators
- Running the Project
- Express.js: A fast and minimalist web framework for Node.js, used to handle HTTP requests and routing.
- Mongoose: An ODM (Object Data Modeling) library for MongoDB, used to interact with the database.
- Typegoose: A wrapper for Mongoose that allows defining models using TypeScript classes and decorators.
- Inversify: A powerful dependency injection (DI) container for TypeScript and JavaScript, used to manage dependencies and promote modularity.
- Zod: A TypeScript-first schema validation library, used for validating input data.
- Pino: A fast and low-overhead logging library, used for structured logging.
- Swagger UI Express: A middleware to serve Swagger API documentation.
- @types/express: TypeScript definitions for Express.
- @types/mongoose: TypeScript definitions for Mongoose.
- pino-pretty: A prettifier for Pino logs to make them more readable during development.
- pino-mongodb: A transport for Pino to store logs in MongoDB.
The project is organized into modules, with each module containing its own controllers, services, and models. The main components include:
src/index.routes.ts
: Handles route setup and registration.src/modules/
: Contains application modules (e.g.,user
module).src/common/
: Shared utilities, configurations, and types.src/exceptions/
: Custom exception handlers.src/configs/
: Configuration files for MongoDB, logging, etc.openapi.json
: OpenAPI specification for API documentation.
-
Clone the repository:
git clone <repository-url> cd <project-folder>
-
Install dependencies:
npm install
-
Set up environment variables: Create a
.env
file in the root directory and add the following variables:PORT=3000 MONGODB_URI=<your-mongodb-uri> MONGODB_DATABASE=<your-database-name>
-
Start the server:
npm start
The API documentation is generated using Swagger and is available at /api-docs
. The OpenAPI specification is defined in the openapi.json
file.
To access the documentation:
- Start the server.
- Navigate to
http://localhost:<PORT>/api-docs
.
The project uses Pino for structured logging. Logs are output in JSON format and can be prettified during development using pino-pretty
. Additionally, logs can be stored in MongoDB using pino-mongodb
.
Example log output:
{
"level": "info",
"time": 1633024800000,
"msg": "Request received: GET /api/v1/users"
}
Dependency Injection (DI) is implemented using Inversify. This allows for better modularity and testability by decoupling dependencies.
Example of DI setup:
import { Container } from 'inversify';
import { UserService } from '@modules/user/user.service';
import { UserController } from '@modules/user/user.controller';
const container = new Container();
container.bind<UserService>(UserService).toSelf();
container.bind<UserController>(UserController).toSelf();
export default container;
Routes are dynamically registered using decorators and metadata reflection. The setupRoutes
function scans controllers and registers routes based on the metadata.
Example route registration:
@Controller('/users')
class UserController {
@Get('/')
getUsers() {
// Handle GET /api/v1/users
}
@Post('/')
createUser() {
// Handle POST /api/v1/users
}
}
Custom decorators are used to define routes and metadata for controllers and methods. These decorators simplify route registration and make the code more declarative.
Example decorators:
@Controller('/users')
class UserController {
@Get('/')
getUsers() {
// Handle GET /api/v1/users
}
@Post('/')
@Middleware(someMiddleware)
createUser() {
// Handle POST /api/v1/users
}
}
- Ensure MongoDB is running and accessible.
- Start the server:
npm start
- The server will be available at
http://localhost:<PORT>
.