Skip to content

usifme/express-mongoose-oop-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Express.js + Mongoose OOP Template

A production-ready Express.js REST API template built with 3 years of real-world experience
Crafted with best practices, scalability, and developer experience in mind.

TypeScript Node.js Express MongoDB License


πŸ‘¨β€πŸ’» About This Template

This template represents 3 years of hands-on experience building and scaling Express.js applications. It consolidates the best practices, architectural patterns, and production-ready features I've learned while working on numerous projects.

What makes this different?

  • ✨ Battle-tested architecture - Used in real production applications
  • πŸ—οΈ True OOP principles - Clean, maintainable, and scalable code structure
  • πŸš€ Production-ready - Not just a starter, but a complete foundation
  • πŸ“š Full documentation - Including Swagger API docs out of the box
  • πŸ”’ Security-first - Rate limiting, JWT auth, input validation, and more
  • πŸ› οΈ Developer experience - TypeScript, hot reload, logging, error handling

✨ Key Features

πŸ›οΈ Architecture & Design

  • Clean OOP Architecture - Repository β†’ Service β†’ Controller pattern
  • TypeScript - Full type safety across the entire codebase
  • Modular Structure - Easy to extend with new modules
  • Base Classes - Reduce boilerplate with BaseRepository and BaseService
  • Dependency Injection - Loosely coupled, testable code

πŸ” Security & Authentication

  • JWT Authentication - Secure token-based auth
  • Password Hashing - Bcrypt with salt rounds
  • Role-Based Access Control (RBAC) - Admin, User, and custom roles
  • Rate Limiting - Prevent API abuse with configurable limits
  • Security Headers - Helmet.js for HTTP security
  • CORS Configuration - Cross-origin resource sharing control
  • Input Validation - Express-validator for request validation

πŸ“Š Database & Data Layer

  • Mongoose ODM - Elegant MongoDB object modeling
  • Base Repository - Generic CRUD operations with pagination
  • Soft Delete Support - Mark as deleted without removing data
  • Query Builder - Fluent interface for complex queries
  • Pagination - Built-in pagination support
  • Indexing - Optimized database queries

🎯 API Features

  • RESTful Design - Industry-standard REST API principles
  • Swagger Documentation - Auto-generated interactive API docs
  • Custom Response Methods - res.sendSuccess(), res.sendError(), res.sendCreated()
  • Request Correlation ID - Track requests across logs
  • File Upload - Multer integration for file handling
  • Search & Filter - Advanced query capabilities

πŸ“ˆ Monitoring & Logging

  • Winston Logger - Production-grade logging with daily rotation
  • Health Checks - /health, /health/live, /health/ready
  • Request Logging - Morgan HTTP request logger
  • Error Tracking - Centralized error handling with stack traces
  • Performance Monitoring - CPU, memory, and database health

πŸ› οΈ Developer Experience

  • TypeScript - IntelliSense, type checking, and refactoring support
  • Hot Reload - Nodemon for automatic server restart
  • Environment Variables - Dotenv for configuration management
  • Code Organization - Clear folder structure and naming conventions
  • Example Modules - Auth, User, and Product modules included

πŸ“ Project Structure

β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ modules/                    # Feature modules
β”‚   β”‚   β”œβ”€β”€ auth/                   # Authentication (register, login, JWT)
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.types.ts      # TypeScript interfaces
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.repository.ts # Data access layer
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.service.ts    # Business logic
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.controller.ts # HTTP handlers
β”‚   β”‚   β”‚   └── auth.routes.ts     # Route definitions
β”‚   β”‚   β”œβ”€β”€ user/                   # User management
β”‚   β”‚   β”‚   β”œβ”€β”€ user.types.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ user.repository.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ user.service.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ user.controller.ts
β”‚   β”‚   β”‚   └── user.routes.ts
β”‚   β”‚   └── product/                # Product CRUD (example)
β”‚   β”‚       β”œβ”€β”€ product.types.ts
β”‚   β”‚       β”œβ”€β”€ product.repository.ts
β”‚   β”‚       β”œβ”€β”€ product.service.ts
β”‚   β”‚       β”œβ”€β”€ product.controller.ts
β”‚   β”‚       └── product.routes.ts
β”‚   β”‚
β”‚   β”œβ”€β”€ shared/                     # Shared utilities
β”‚   β”‚   β”œβ”€β”€ config/                 # Configuration
β”‚   β”‚   β”‚   β”œβ”€β”€ index.ts           # Environment config
β”‚   β”‚   β”‚   └── swagger.ts         # Swagger/OpenAPI config
β”‚   β”‚   β”œβ”€β”€ database/              # Database layer
β”‚   β”‚   β”‚   β”œβ”€β”€ BaseRepository.ts  # Generic CRUD repository
β”‚   β”‚   β”‚   β”œβ”€β”€ BaseService.ts     # Generic service layer
β”‚   β”‚   β”‚   └── models/            # Mongoose models
β”‚   β”‚   β”‚       β”œβ”€β”€ User.model.ts
β”‚   β”‚   β”‚       └── Product.model.ts
β”‚   β”‚   β”œβ”€β”€ middlewares/           # Express middlewares
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.middleware.ts          # JWT & RBAC
β”‚   β”‚   β”‚   β”œβ”€β”€ validation.middleware.ts    # Input validation
β”‚   β”‚   β”‚   β”œβ”€β”€ errorHandler.middleware.ts  # Error handling
β”‚   β”‚   β”‚   β”œβ”€β”€ responseHandler.middleware.ts # Response methods
β”‚   β”‚   β”‚   β”œβ”€β”€ correlationId.middleware.ts # Request tracking
β”‚   β”‚   β”‚   └── rateLimiter.middleware.ts   # Rate limiting
β”‚   β”‚   └── utils/                 # Utility functions
β”‚   β”‚       β”œβ”€β”€ logger.ts          # Winston logger
β”‚   β”‚       β”œβ”€β”€ response.helper.ts # Response formatting
β”‚   β”‚       β”œβ”€β”€ healthCheck.ts     # Health monitoring
β”‚   β”‚       β”œβ”€β”€ queryBuilder.ts    # Query builder
β”‚   β”‚       └── fileUpload.ts      # File upload utility
β”‚   β”‚
β”‚   β”œβ”€β”€ types/                     # TypeScript definitions
β”‚   β”‚   β”œβ”€β”€ index.ts              # Common types
β”‚   β”‚   └── express.d.ts          # Express augmentation
β”‚   β”‚
β”‚   β”œβ”€β”€ app.ts                     # Express app setup
β”‚   └── index.ts                   # Server entry point
β”‚
β”œβ”€β”€ uploads/                       # Uploaded files
β”œβ”€β”€ logs/                          # Log files
β”œβ”€β”€ dist/                          # Compiled JavaScript
β”œβ”€β”€ .env.example                   # Environment template
β”œβ”€β”€ tsconfig.json                  # TypeScript config
β”œβ”€β”€ package.json                   # Dependencies
β”œβ”€β”€ README.md                      # This file

πŸš€ Quick Start

Prerequisites

  • Node.js >= 18.x
  • MongoDB >= 6.x
  • npm or yarn

Installation

  1. Clone the repository
git clone https://github.com/itsusif/express-mongoose-oop-template.git
cd express-mongoose-oop-template
  1. Install dependencies
npm install
  1. Set up environment variables
cp .env.example .env
  1. Configure your .env file
# Server Configuration
PORT=3000
NODE_ENV=development

# Database
MONGODB_URI=mongodb://localhost:27017/your-database-name

# JWT Authentication
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
JWT_EXPIRES_IN=7d

# CORS
CORS_ORIGIN=http://localhost:3000

# Rate Limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
  1. Start the development server
npm run dev
  1. Visit the API documentation
http://localhost:3000/api-docs

πŸ“š API Documentation

This template includes Swagger/OpenAPI documentation out of the box.

Access the interactive API docs:

http://localhost:3000/api-docs

Main Endpoints

πŸ” Authentication

POST   /api/auth/register    # Register new user
POST   /api/auth/login       # Login and get JWT token

πŸ‘€ Users

GET    /api/users/profile    # Get current user profile (Auth required)
PUT    /api/users/profile    # Update profile (Auth required)
GET    /api/users            # Get all users with pagination (Admin only)
DELETE /api/users/:id        # Delete user (Admin only)

πŸ“¦ Products

POST   /api/products                    # Create product (Auth required)
GET    /api/products                    # Get all products (paginated)
GET    /api/products/:id                # Get product by ID
PUT    /api/products/:id                # Update product (Owner only)
DELETE /api/products/:id                # Delete product (Owner only)
GET    /api/products/category/:category # Filter by category
GET    /api/products/search?q=keyword   # Search products

πŸ’š Health Checks

GET    /health              # Detailed system health
GET    /health/live         # Liveness probe
GET    /health/ready        # Readiness probe

πŸ—οΈ Architecture Explained

🎯 Layered Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         HTTP Request                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Middlewares                    β”‚
β”‚  (Auth, Validation, CORS, etc.)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Controller                  β”‚
β”‚  (Handle HTTP, call service)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          Service                    β”‚
β”‚   (Business logic, validation)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        Repository                   β”‚
β”‚   (Database operations)             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       MongoDB Database              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Code Example

1. Repository Layer (Data Access)

export class ProductRepository extends BaseRepository<IProduct> {
  constructor() {
    super(ProductModel);
  }
  
  async findByCategory(category: string): Promise<IProduct[]> {
    return await this.model.find({ category, isActive: true }).exec();
  }
}

2. Service Layer (Business Logic)

export class ProductService {
  private repository: ProductRepository;
  
  async createProduct(userId: string, data: CreateProductDTO): Promise<ProductResponseDTO> {
    // Validate business rules
    if (data.price < 0) {
      throw new AppError('Price cannot be negative', 400);
    }
    
    const product = await this.repository.create({
      ...data,
      createdBy: userId
    });
    
    return this.mapToDTO(product);
  }
}

3. Controller Layer (HTTP Handling)

export class ProductController {
  private service: ProductService;
  
  createProduct = async (req: AuthRequest, res: Response, next: NextFunction) => {
    try {
      const userId = req.user!.id;
      const result = await this.service.createProduct(userId, req.body);
      
      // Clean response with custom method
      res.sendCreated(result, 'Product created successfully');
    } catch (error) {
      next(error);
    }
  }
}

4. Routes (Endpoint Definition)

export class ProductRoutes {
  initializeRoutes() {
    this.router.post(
      '/',
      AuthMiddleware.authenticate,
      ValidationMiddleware.validate(createValidation),
      RateLimiterMiddleware.moderate,
      this.controller.createProduct
    );
  }
}

🎯 Usage Examples

Example 1: Creating a New Module

Let's create a Category module:

  1. Create the structure:
mkdir -p src/modules/category
  1. Define types (category.types.ts):
export interface CreateCategoryDTO {
  name: string;
  slug: string;
  description?: string;
}

export interface CategoryResponseDTO {
  id: string;
  name: string;
  slug: string;
  description?: string;
  createdAt: Date;
}
  1. Create repository (category.repository.ts):
import { BaseRepository } from '../../shared/database/BaseRepository';
import { CategoryModel, ICategory } from '../../shared/database/models/Category.model';

export class CategoryRepository extends BaseRepository<ICategory> {
  constructor() {
    super(CategoryModel);
  }
}
  1. Create service using BaseService (category.service.ts):
import { BaseService } from '../../shared/database/BaseService';
import { CategoryRepository } from './category.repository';
import { CreateCategoryDTO, CategoryResponseDTO } from './category.types';

export class CategoryService extends BaseService<
  ICategory,
  CreateCategoryDTO,
  any,
  CategoryResponseDTO
> {
  constructor() {
    super(new CategoryRepository());
  }
  
  protected mapToDTO(item: ICategory): CategoryResponseDTO {
    return {
      id: item._id.toString(),
      name: item.name,
      slug: item.slug,
      description: item.description,
      createdAt: item.createdAt
    };
  }
}

Example 2: Using Query Builder

import { QueryBuilder } from '../shared/utils/queryBuilder';

// Complex query made simple
const activeUsers = await new QueryBuilder(UserModel)
  .where('isActive', true)
  .where('role', 'user')
  .greaterThan('createdAt', new Date('2024-01-01'))
  .search('john')
  .sort('createdAt', 'desc')
  .paginate(1, 10)
  .populate('profile', 'name email')
  .select('name email role createdAt')
  .execute();

Example 3: File Upload

import { FileUploadUtil } from '../shared/utils/fileUpload';

// In routes
router.post(
  '/upload-avatar',
  AuthMiddleware.authenticate,
  FileUploadUtil.uploadImage.single('avatar'),
  userController.uploadAvatar
);

// In controller
uploadAvatar = async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    if (!req.file) {
      return res.sendError('No file uploaded', 400);
    }
    
    const fileUrl = FileUploadUtil.getFileUrl(
      req.file.filename,
      `${req.protocol}://${req.get('host')}`
    );
    
    await this.userService.updateAvatar(req.user!.id, fileUrl);
    
    res.sendSuccess({ url: fileUrl }, 'Avatar uploaded successfully');
  } catch (error) {
    next(error);
  }
};

πŸ› οΈ Available Scripts

# Development
npm run dev              # Start dev server with hot reload
npm run build            # Build for production
npm start                # Start production server

# Code Quality
npm run lint             # Run ESLint
npm run format           # Format code with Prettier
npm test                 # Run tests (if configured)

πŸ”§ Configuration

Environment Variables

All configuration is done through environment variables. See .env.example for all available options.

Key configurations:

Variable Description Default
PORT Server port 3000
NODE_ENV Environment (development/production) development
MONGODB_URI MongoDB connection string -
JWT_SECRET JWT signing secret -
JWT_EXPIRES_IN Token expiration 7d
RATE_LIMIT_WINDOW_MS Rate limit window 900000 (15 min)
RATE_LIMIT_MAX_REQUESTS Max requests per window 100

πŸ“– Learn More


🀝 Contributing

Contributions are welcome! If you have suggestions for improvements:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ‘€ Author

Youssef Naguib

This template is the result of 3 years of building and scaling Express.js applications in production. It consolidates patterns, practices, and solutions that have proven effective across multiple real-world projects.

🌐 Connect with me:


⭐ Show Your Support

If this template helped you build better Express.js applications, please give it a ⭐️ on GitHub!


πŸ™ Acknowledgments

This template incorporates best practices from:

  • Express.js official documentation
  • Node.js design patterns
  • Clean Architecture principles
  • Real-world production experience

Built with ❀️ by Youssef Naguib

Making Express.js development easier, one template at a time

GitHub LinkedIn Website

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors