nestjs-monorepo

repository·main·Indexed 18 days ago

https://github.com/mikemajesty/nestjs-monorepo

A NestJS monorepo boilerplate for scalable microservices. It features built-in support for Docker, observability via Jaeger and Kibana, authentication, and structured shared libraries. The project includes a dedicated CLI for scaffolding new features and provides reference implementations through the auth-api and cats-api services.

Tokens
4.1K
Snippets
20
Records
25
Agent score
64%

What's inside nestjs-monorepo

  1. Understand the Monorepo Architecture

    main

    The repository is organized into several top-level directories to separate concerns:

    • apps/: Contains the deployable applications.
      • auth-api: Handles authentication and token generation.
      • cats-api: Serves as a reference implementation for creating new APIs.
    • libs/: Shared libraries used across applications.
      • core: Contains core business rules. Note: Do not use NestJS dependencies here; use only plain classes and rules.
      • modules: Contains NestJS-specific modules (e.g., HTTP, Database, Redis, Secrets).
      • utils: Shared utilities used throughout the monorepo.
    • tools/: Project-specific tooling like ESLint and Prettier.
    • tests/: Monorepo test initializers (env, mocks, and configs).
  2. Create an Access User and Get an Auth Token

    main

    To access internal APIs, you must first create a user in the MongoDB monorepo_auth database and then exchange those credentials for a token.

    1. Create User in Mongo: Access http://0.0.0.0:8082/db/monorepo_auth/users and create a new document with this structure:

      {
         "_id": ObjectID(),
         "login": "<user>",
         "pass": "<pass>"
      }
    2. Retrieve Token via Curl: Use the following command to get your access token:

      curl -X 'POST' 'http://0.0.0.0:4000/api/login' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "login": "<user>", "pass": "<pass>" }'

    Use the returned token to authenticate all other monorepo internal APIs.

    curl -X 'POST' 'http://0.0.0.0:4000/api/login' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "login": "<user>", "pass": "<pass>" }'
  3. Manage Workspace Dependencies

    main

    The monorepo uses Yarn workspaces. Use the following commands to manage dependencies for specific projects or libraries:

    • Install dependencies for a specific workspace:
      yarn workspace <workspaceName> install
    • Add a library to a specific workspace:
      yarn workspace <workspaceName> add <libName>

    To see a list of all available workspaces, run:

    yarn workspaces info

    Available workspaces include:

    • @app/cats.api
    • @app/auth.api
    • @tools/eslint.config
    • @libs/utils
    • @libs/modules
    • @libs/core
    $ yarn workspaces info
  4. Run Local Infrastructure (Mongo, Redis, Kibana, Jaeger)

    main

    To spin up the required local infrastructure services using Docker, run:

    yarn infra:local

    Once running, you can access the services at these endpoints:

    • MongoDB: http://0.0.0.0:8082/
    • Redis: http://0.0.0.0:8081/
    • Kibana: http://0.0.0.0:5601/app/home
    • Jaeger: http://0.0.0.0:16686/search
    $ yarn infra:local
  5. Run the Applications

    main

    You can run the applications in two ways:

    Local Development

    Run individual APIs in development mode:

    yarn start:auth-api:dev
    yarn start:cats-api:dev

    Docker Compose (dev/hml/prd environments)

    To build and run the entire stack using Docker Compose:

    docker-compose up --build
    yarn start:auth-api:dev
    # or
    docker-compose up --build
  6. Add New Features via CLI

    main

    You can use the dedicated monorepo CLI to scaffold new features using templates:

    1. Install the CLI globally:
      npm i -g @mikemajesty/monorepo-nestjs-cli
    2. Run the generator:
      monorepo-nestjs-cli
      Follow the interactive prompts to choose your template.
    npm i -g @mikemajesty/monorepo-nestjs-cli
    monorepo-nestjs-cli
  7. Run Tests and Coverage

    main

    The project supports unit, e2e, and coverage testing.

    Unit Tests

    • Run all monorepo tests: yarn test
    • Run specific project tests:
      • yarn test main.api
      • yarn test auth.api
      • yarn test libs

    End-to-End (e2e) Tests

    • yarn test:e2e

    Test Coverage

    • yarn test:coverage
    yarn test
    yarn test:e2e
    yarn test:coverage
  8. Start the auth-api service

    main

    The auth-api service is a NestJS application that bootstraps the authentication logic. When running, it configures global validation pipes, exception filters, and interceptors for logging and tracing. It also exposes a Swagger/OpenAPI documentation endpoint.

    Key behaviors:

    • Global Prefix: All routes are prefixed with api/, except for the health GET endpoint.
    • Validation: Uses ValidationPipe with errorHttpStatusCode set to HttpStatus.PRECONDITION_FAILED.
    • Documentation: Swagger documentation is served at the path defined by SWAGGER_API_ROOT.
    • Observability: Integrates with ILoggerService for application logging and uses TracingInterceptor for distributed tracing.
    // The service is bootstrapped via the bootstrap() function in main.ts
    // It relies on MainModule and ISecretsService for configuration.
    await app.listen(PORT);
  9. Start the cats-api service

    main

    The cats-api service is a NestJS application that bootstraps a microservice with built-in support for validation, logging, tracing, and Swagger documentation.

    When running, the service:

    • Uses ValidationPipe with HttpStatus.PRECONDITION_FAILED for error handling.
    • Implements global filters (AppExceptionFilter) and interceptors (ExceptionInterceptor, HttpLoggerInterceptor, TracingInterceptor) for unified error handling and observability.
    • Sets a global API prefix of api, excluding the health GET endpoint.
    • Exposes Swagger documentation at the path defined by SWAGGER_API_ROOT.
    • Retrieves configuration (ports, URLs for external services like Mongo, Redis, Kibana, and Jaeger) via the ISecretsService.

    To start the service, the bootstrap() function is executed, which initializes the Nest application using MainModule.

    // The service is started by executing the bootstrap function in main.ts
    // It relies on MainModule and various global providers like ILoggerService and ISecretsService
    await app.listen(PORT);