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

29 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 18+
  • 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 npm scripts from package.json for convenience.

# Build and start containers in detached mode for development
$ npm run docker:dev

# Build and start containers for production
$ npm run docker:prod

# View logs for the API service
$ npm run docker:logs

# Stop all running containers
$ npm run docker:down

# Restart the development environment
$ npm run docker:restart

🌐 Service Access

πŸ“¦ Installation

$ npm install

πŸš€ Running the Application

# Development
$ npm run start

# Watch mode (recommended for development)
$ npm run start:dev

# Production mode
$ npm run start:prod

# Debug mode
$ npm run start:debug

πŸ§ͺ Testing

# Unit tests
$ npm run test

# E2E tests
$ npm run test:e2e

# Test coverage
$ npm run test:cov

# Watch mode
$ npm run test:watch

πŸ§ͺ 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