Skip to content

A modular NestJS boilerplate with CQRS, Event Sourcing, DDD, Clean Architecture, and MongoDB. Built-in observability with Prometheus & Grafana, API docs via Swagger, and Dockerized deployment. Ideal for scalable, maintainable applications.

License

Notifications You must be signed in to change notification settings

CollatzConjecture/nestjs-clean-architecture

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

40 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

NestJS Clean Architecture with DDD, CQRS & Event Sourcing

This is an advanced boilerplate project implementing Domain-Driven Design (DDD), Clean Architecture, CQRS (Command Query Responsibility Segregation), Event Sourcing and MongoDB with NestJS. It provides a robust foundation for building scalable and maintainable enterprise-level applications with proper separation of concerns and clean dependency direction.

If you want more documentation about NestJS, click here Nest

πŸ“ Note: This version uses MongoDB with Mongoose. If you prefer the PostgreSQL version with TypeORM, you can find it at the original repository: https://github.com/CollatzConjecture/nestjs-clean-architecture-postgres

A quick introduction to clean architecture

Clean Architecture

πŸš€ Features

Core Architecture

  • Clean Architecture: Enforces strict separation of concerns with proper dependency direction (Infrastructure β†’ Application β†’ Domain).
  • Domain-Driven Design (DDD): Pure business logic encapsulated in Domain Services, accessed through Repository Interfaces.
  • CQRS: Segregates read (Queries) and write (Commands) operations for optimized performance and scalability.
  • Event Sourcing: Uses an event-driven approach with sagas for orchestrating complex business processes.
  • Repository Pattern: Clean interfaces defined in Domain layer, implemented in Infrastructure layer.
  • Dependency Inversion: Domain layer depends only on abstractions, never on concrete implementations.

Proper Layer Separation

  • Domain Layer: Pure business logic, domain entities without framework dependencies, repository interfaces
  • Application Layer: Business orchestration, application services, CQRS coordination, framework-agnostic services
  • API Layer: HTTP controllers, DTOs, request/response handling, framework-specific HTTP concerns
  • Infrastructure Layer: Database implementations, external API calls, concrete repository classes, global services

Security & Authentication

  • JWT Authentication: Implements secure, token-based authentication with refresh token rotation.
  • Google OAuth2 Integration: Secure third-party authentication with Google accounts, including CSRF protection.
  • Role-Based Access Control (RBAC): Complete implementation with protected routes and role-based guards.
  • Secure Password Storage: Hashes passwords using bcrypt with salt rounds.
  • Sensitive Data Encryption: Encrypts sensitive fields (e.g., user emails) at rest in the database using AES-256-CBC.
  • Blind Indexing: Allows for securely querying encrypted data without decrypting it first.
  • CSRF Protection: OAuth flows protected against Cross-Site Request Forgery attacks using state parameters.

Infrastructure & Operations

  • MongoDB Integration: Utilizes Mongoose for structured data modeling with a NoSQL database.
  • Containerized Environment: Full Docker and Docker Compose setup for development and production.
  • Health Checks: Provides application health monitoring endpoints via Terminus.
  • Structured Logging: Advanced logging system with business-context awareness and dependency injection.
  • Application Metrics: Exposes performance metrics for Prometheus.
  • Data Visualization: Comes with a pre-configured Grafana dashboard for visualizing metrics.
  • Request Throttling: Built-in rate limiting to prevent abuse and ensure API stability.

Testing

  • Unit & Integration Tests: A suite of tests for domain, application, and infrastructure layers.
  • E2E Tests: End-to-end tests to ensure API functionality from request to response.
  • High Test Coverage: Configured to report and maintain high code coverage.
  • Mocking: Clear patterns for mocking database and service dependencies.

Getting Started

git clone https://github.com/CollatzConjecture/nestjs-clean-architecture cd nestjs-clean-architecture

πŸ“ Project Structure

. β”œβ”€β”€ doc/ β”‚ β”œβ”€β”€ common.http # Common API requests β”‚ └── users.http # User-specific API requests β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ api/ # API Layer (HTTP Controllers & DTOs) β”‚ β”‚ β”œβ”€β”€ controllers/ β”‚ β”‚ β”‚ └── *.controller.ts # HTTP endpoints (auth, profile, hello) β”‚ β”‚ β”œβ”€β”€ dto/ β”‚ β”‚ β”‚ β”œβ”€β”€ auth/ # Authentication DTOs β”‚ β”‚ β”‚ β”‚ └── *.dto.ts # Login & register DTOs β”‚ β”‚ β”‚ └── *.dto.ts # Profile management DTOs β”‚ β”‚ └── api.module.ts # API module configuration β”‚ β”œβ”€β”€ application/ # Application Layer (Business Orchestration) β”‚ β”‚ β”œβ”€β”€ __test__/ β”‚ β”‚ β”‚ └── *.spec.ts # Application layer tests β”‚ β”‚ β”œβ”€β”€ auth/ β”‚ β”‚ β”‚ β”œβ”€β”€ command/ # Auth commands & handlers β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ *.command.ts # Create/delete auth user commands β”‚ β”‚ β”‚ β”‚ └── handler/ β”‚ β”‚ β”‚ β”‚ └── *.handler.ts # Command handlers β”‚ β”‚ β”‚ β”œβ”€β”€ events/ # Auth domain events β”‚ β”‚ β”‚ β”‚ └── *.event.ts # User created/deleted events β”‚ β”‚ β”‚ β”œβ”€β”€ sagas/ β”‚ β”‚ β”‚ β”‚ └── *.saga.ts # Registration flow orchestration β”‚ β”‚ β”‚ β”œβ”€β”€ decorators/ β”‚ β”‚ β”‚ β”‚ └── *.decorator.ts # Custom decorators (roles) β”‚ β”‚ β”‚ β”œβ”€β”€ guards/ β”‚ β”‚ β”‚ β”‚ └── *.guard.ts # Authentication & authorization guards β”‚ β”‚ β”‚ β”œβ”€β”€ *.strategy.ts # Auth strategies (JWT, local, Google OAuth) β”‚ β”‚ β”‚ └── auth.module.ts # Auth module configuration β”‚ β”‚ β”œβ”€β”€ decorators/ β”‚ β”‚ β”‚ └── *.decorator.ts # Global decorators (current user) β”‚ β”‚ β”œβ”€β”€ interfaces/ β”‚ β”‚ β”‚ └── *.interface.ts # Application interfaces β”‚ β”‚ β”œβ”€β”€ interceptors/ β”‚ β”‚ β”‚ └── *.interceptor.ts # Request logging interceptors β”‚ β”‚ β”œβ”€β”€ middlewere/ β”‚ β”‚ β”‚ └── *.middleware.ts # HTTP middleware (logging) β”‚ β”‚ β”œβ”€β”€ services/ β”‚ β”‚ β”‚ └── *.service.ts # Application services (auth, profile, logger) β”‚ β”‚ β”œβ”€β”€ profile/ β”‚ β”‚ β”‚ β”œβ”€β”€ command/ # Profile commands & handlers β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ *.command.ts # Profile commands β”‚ β”‚ β”‚ β”‚ └── handler/ β”‚ β”‚ β”‚ β”‚ └── *.handler.ts # Command handlers β”‚ β”‚ β”‚ β”œβ”€β”€ events/ # Profile domain events β”‚ β”‚ β”‚ β”‚ └── *.event.ts # Profile events β”‚ β”‚ β”‚ └── profile.module.ts # Profile module configuration β”‚ β”‚ └── application.module.ts # Application module aggregator β”‚ β”œβ”€β”€ domain/ # Domain Layer (Pure Business Logic) β”‚ β”‚ β”œβ”€β”€ __test__/ β”‚ β”‚ β”‚ └── *.spec.ts # Domain layer tests β”‚ β”‚ β”œβ”€β”€ aggregates/ # Domain aggregates β”‚ β”‚ β”œβ”€β”€ entities/ β”‚ β”‚ β”‚ β”œβ”€β”€ *.ts # Pure domain entities (Auth, Profile) β”‚ β”‚ β”‚ └── enums/ # Domain enums β”‚ β”‚ β”‚ └── *.enum.ts # Role enums, etc. β”‚ β”‚ β”œβ”€β”€ interfaces/ β”‚ β”‚ β”‚ └── repositories/ # Repository contracts defined by domain β”‚ β”‚ β”‚ └── *.interface.ts # Repository interfaces β”‚ β”‚ └── services/ β”‚ β”‚ └── *.service.ts # Pure business logic services β”‚ β”œβ”€β”€ infrastructure/ # Infrastructure Layer (External Concerns) β”‚ β”‚ β”œβ”€β”€ database/ β”‚ β”‚ β”‚ β”œβ”€β”€ database.module.ts # Database configuration β”‚ β”‚ β”‚ └── database.providers.ts # Database providers β”‚ β”‚ β”œβ”€β”€ health/ β”‚ β”‚ β”‚ └── *.check.ts # Health check configurations β”‚ β”‚ β”œβ”€β”€ logger/ β”‚ β”‚ β”‚ └── logger.module.ts # Global logger module β”‚ β”‚ β”œβ”€β”€ models/ β”‚ β”‚ β”‚ β”œβ”€β”€ *.model.ts # MongoDB models (auth, profile) β”‚ β”‚ β”‚ └── index.ts # Model exports β”‚ β”‚ └── repository/ β”‚ β”‚ └── *.repository.ts # Repository implementations β”‚ β”œβ”€β”€ main.ts # Application entry point β”‚ β”œβ”€β”€ app.module.ts # Root application module β”‚ └── constants.ts # Application constants β”œβ”€β”€ test/ β”‚ β”œβ”€β”€ *.e2e-spec.ts # End-to-end tests β”‚ β”œβ”€β”€ jest-e2e.json # E2E test configuration β”‚ └── setup-e2e.ts # E2E test setup β”œβ”€β”€ prometheus/ β”‚ └── prometheus.yml # Prometheus configuration β”œβ”€β”€ docker-compose*.yml # Docker Compose configurations (dev, prod) └── Dockerfile # Container definition 

πŸ—οΈ Architecture Overview

Layer Architecture

This project follows a strict 4-layer architecture:

  1. API Layer (src/api/): HTTP controllers, DTOs, and request/response handling
  2. Application Layer (src/application/): Business orchestration, CQRS coordination, and application services
  3. Domain Layer (src/domain/): Pure business logic, entities, and domain services
  4. Infrastructure Layer (src/infrastructure/): Database, external services, and technical implementations

Module Structure

  • ApiModule: Aggregates all HTTP controllers and imports ApplicationModule
  • ApplicationModule: Central orchestrator that imports and exports feature modules
  • AuthModule: Self-contained authentication feature with all its dependencies
  • ProfileModule: Self-contained profile management feature with all its dependencies
  • LoggerModule: Global infrastructure service for application-wide logging

CQRS Implementation

  • Commands: Handle write operations (Create, Update, Delete). Located in src/application/*/command.
  • Queries: Handle read operations (Find, Get). Located in src/application/*/query.
  • Handlers: Process commands and queries separately with proper business-context logging.
  • Events: Publish domain events for side effects and inter-module communication.

Event-Driven Flow

  1. User Registration:

    API Controller β†’ Application Service β†’ Domain Service (validation) β†’ RegisterCommand β†’ CreateAuthUser β†’ AuthUserCreated Event β†’ RegistrationSaga β†’ CreateProfile β†’ ProfileCreated 
  2. Authentication:

    API Controller β†’ Application Service β†’ Domain Service (email validation) β†’ LoginCommand β†’ ValidateUser β†’ JWT Token Generation 
  3. Google OAuth Flow:

    /auth/google β†’ Google OAuth β†’ /auth/google/redirect β†’ Domain Service (validation) β†’ FindOrCreateUser β†’ JWT Token Generation 
  4. Error Handling:

    ProfileCreationFailed Event β†’ RegistrationSaga β†’ DeleteAuthUser (Compensating Transaction) 

Dependency Injection & Module Boundaries

  • Feature Modules: Each feature (Auth, Profile) manages its own dependencies
  • Domain Services: Injected via factories to maintain Clean Architecture principles
  • Repository Pattern: Interfaces defined in domain, implementations in infrastructure
  • Global Services: Logger provided globally via @Global() decorator

πŸ“‹ Prerequisites

  • Node.js 20+
  • Docker and Docker Compose
  • MongoDB (included in Docker Compose)
  • Google OAuth2 credentials (for Google login functionality)

🐳 Running with Docker Compose

The project is configured to run seamlessly with Docker. Use the pnpm scripts from package.json for convenience.

# Build and start containers in detached mode for development $ pnpm run docker:dev # Build and start containers for production $ pnpm run docker:prod # View logs for the API service $ pnpm run docker:logs # Stop all running containers $ pnpm run docker:down # Restart the development environment $ pnpm run docker:restart

🌐 Service Access

πŸ“¦ Installation

$ pnpm install

πŸš€ Running the Application

# Development $ pnpm run start # Watch mode (recommended for development) $ pnpm run start:dev # Production mode $ pnpm run start:prod # Debug mode $ pnpm run start:debug

πŸ§ͺ Testing

# Unit tests $ pnpm run test # E2E tests $ pnpm run test:e2e # Test coverage $ pnpm run test:cov # Watch mode $ pnpm run test:watch

🧹 Linting

# Check code style $ pnpm run lint # Auto-fix issues where possible $ pnpm run lint:fix

πŸ§ͺ API Testing

You can import this Postman collection to test the API endpoints.

The collection includes:

  • Authentication endpoints: Register, login, logout, Google OAuth
  • Profile management: Create, read, update profile data
  • Protected routes: Examples with JWT token authentication
  • Admin endpoints: Role-based access control examples
  • Environment variables: Pre-configured for localhost development

Using the Postman Collection

  1. Import the collection: Download and import NestJS CA-DDD.postman_collection.json into Postman
  2. Set environment variables: Configure the following variables in Postman:
    • localhost: http://localhost (or your host)
    • port: 4000 (or your configured port)
    • Authorization: Bearer <your-jwt-token> (set after login)
  3. Test the flow:
    • Start with user registration
    • Login to get JWT token
    • Use the token for protected endpoints

πŸ” API Endpoints

Authentication

POST /auth/register # User registration POST /auth/login # User login POST /auth/logout # User logout (Protected) POST /auth/refresh-token # Token refresh (Protected) GET  /auth/google # Initiate Google OAuth login GET  /auth/google/redirect # Google OAuth callback GET  /auth/:id # Get user by auth ID (Protected) DELETE /auth/:id # Delete user by auth ID (Protected)

Profile Management (Protected)

GET  /profile/all # Get all user profiles (Admin only) GET  /profile/admins # Get all admin users (Admin only) GET  /profile/:id # Get user profile by ID POST /profile # Create a new profile

Health & Monitoring

GET  /hello # Health check endpoint GET  /health # Detailed health check GET  /metrics # Prometheus metrics

Example Usage

Traditional Registration & Login

# Register a new user curl -X POST http://localhost:4000/auth/register \ -H "Content-Type: application/json" \ -d '{  "name": "John",  "lastname": "Doe",  "age": 30,  "email": "john@example.com",  "password": "securePassword123"  }' # Login curl -X POST http://localhost:4000/auth/login \ -H "Content-Type: application/json" \ -d '{  "email": "john@example.com",  "password": "securePassword123"  }'

Google OAuth Login

# Initiate Google login (redirects to Google) curl -X GET http://localhost:4000/auth/google # The callback is handled automatically after Google authentication # Returns JWT token upon successful authentication

Protected Routes

# Access protected route curl -X GET http://localhost:4000/profile/123 \ -H "Authorization: Bearer YOUR_JWT_TOKEN" # Admin-only route curl -X GET http://localhost:4000/profile/all \ -H "Authorization: Bearer YOUR_ADMIN_JWT_TOKEN"

πŸ› οΈ Built With

Core Framework

Architecture & Patterns

Authentication & Security

Database & Storage

Monitoring & Health

Testing

Development Tools

πŸ›οΈ Domain-Driven Design

Bounded Contexts

  • Authentication Context: User login, registration, tokens, OAuth integration
  • Profile Context: User profile management, personal data

Aggregates

  • UserAggregate: Manages user lifecycle and events across auth and profile contexts

Domain Events

  • AuthUserCreatedEvent: Triggered after successful user creation
  • AuthUserDeletedEvent: Triggered when user is deleted (compensating action)
  • ProfileCreationFailedEvent: Triggered when profile creation fails

Sagas

  • RegistrationSaga: Orchestrates user registration process
    • Handles profile creation after auth user creation
    • Implements compensating transactions for failures
    • Supports both traditional and OAuth registration flows

πŸ“ˆ Monitoring & Observability

Structured Logging

  • Business-Context Logging: Logs focus on business events rather than technical execution
  • Dependency Injection: Logger service is injected throughout the application
  • Consistent Format: All logs include module, method, and timestamp information
  • Security Audit Trail: Comprehensive logging of authentication attempts and outcomes

Health Checks

  • Database connectivity
  • Memory usage
  • Disk space

Metrics (Prometheus)

  • HTTP request duration
  • Request count by endpoint
  • Error rates
  • Database connection pool
  • Authentication success/failure rates

Dashboards (Grafana)

  • Application performance metrics
  • Database statistics
  • Error tracking
  • Response time analysis
  • Authentication analytics

βš™οΈ Configuration

  1. Clone the repository:

    git clone https://github.com/CollatzConjecture/nestjs-clean-architecture cd nestjs-clean-architecture
  2. Create an environment file:

    Create a file named .env in the root of the project by copying the example file.

    cp .env.example .env
  3. Generate Secrets:

    Your .env file requires several secret keys to run securely. Use the following command to generate a cryptographically strong secret:

    node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

    Run this command for each of the following variables in your .env file and paste the result:

    • JWT_SECRET
    • JWT_REFRESH_SECRET
    • EMAIL_ENCRYPTION_KEY
    • EMAIL_BLIND_INDEX_SECRET

    Do not use the same value for different keys.

  4. Configure Google OAuth2 (Optional):

    To enable Google login functionality, you'll need to:

    a. Go to the Google Cloud Console

    b. Create a new project or select an existing one

    c. Enable the Google+ API

    d. Create OAuth 2.0 credentials (Web application type)

    e. Add your redirect URI: http://localhost:4000/auth/google/redirect

    f. Add the following to your .env file:

    GOOGLE_CLIENT_ID=your_google_client_id_here GOOGLE_CLIENT_SECRET=your_google_client_secret_here GOOGLE_CALLBACK_URL=http://localhost:4000/auth/google/redirect

πŸ”’ Security Features

Authentication Security

  • JWT with Refresh Tokens: Secure token-based authentication with automatic refresh
  • Password Security: Bcrypt hashing with configurable salt rounds
  • OAuth2 Security: CSRF protection using state parameters in OAuth flows
  • Rate Limiting: Configurable throttling on sensitive endpoints

Data Protection

  • Encryption at Rest: Sensitive data encrypted using AES-256-CBC
  • Blind Indexing: Secure querying of encrypted data
  • Input Validation: Comprehensive DTO validation using class-validator
  • SQL Injection Prevention: MongoDB with Mongoose provides built-in protection
  • Automatic Timestamps: All models include createdAt and updatedAt for audit trails

Access Control

  • Role-Based Authorization: Complete RBAC implementation with guards
  • Route Protection: JWT guards on sensitive endpoints
  • Admin Controls: Separate endpoints for administrative functions

πŸ‘¨β€πŸ’» Authors

  • Jerry Lucas - Current Maintainer - GitHub

πŸ“„ License

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

πŸ™ Acknowledgments

  • Edwin Caminero - Inspiration for this project
  • Clean Architecture principles by Robert C. Martin
  • Domain-Driven Design concepts by Eric Evans
  • CQRS and Event Sourcing patterns
  • NestJS framework and community

πŸ“š Further Reading

About

A modular NestJS boilerplate with CQRS, Event Sourcing, DDD, Clean Architecture, and MongoDB. Built-in observability with Prometheus & Grafana, API docs via Swagger, and Dockerized deployment. Ideal for scalable, maintainable applications.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages