Backend III
This section covers the essential backend technologies and architecture you'll be working with when using the NestJS framework. Review these documents to understand our server-side infrastructure and development practices for the Courier Integration Service.
Overview
- NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. It is built with and fully supports TypeScript.
- NestJS uses Express under the hood by default (or optionally Fastify), but provides a higher-level abstraction that enforces a structured, opinionated architecture inspired by Angular.
Why choose NestJS?
- First-class TypeScript support with decorators and metadata reflection.
- Structured, modular architecture that scales cleanly for large applications.
- Powerful built-in dependency injection (DI) container for loosely coupled services.
- Rich ecosystem of official modules (config, validation, queues, schedulers, etc.).
- Excellent support for REST APIs, GraphQL, WebSockets, and microservices.
Core Concepts
Modules
NestJS applications are organized into Modules. Every app has at least one root module (AppModule) and can have any number of feature modules. Modules define providers, controllers, and imports/exports to encapsulate related functionality.
Controllers
Controllers handle incoming HTTP requests and return responses. They use decorators like @Get(), @Post(), @Param(), and @Body() to define routes and extract request data.
Providers & Services
Providers (typically Services) contain the business logic and are injected into controllers and other services via NestJS's DI system. Annotate a class with @Injectable() to make it a provider.
Decorators
NestJS makes heavy use of TypeScript decorators to attach metadata to classes and methods. Common decorators include @Controller(), @Injectable(), @Module(), @Get(), @Post(), @Body(), @Param(), @Query(), and @UseGuards().
Routing & Middleware
- Routes are defined declaratively using method decorators on controller methods.
- Middleware in NestJS can be applied globally, per-module, or per-route via the
configure()method in a module or usingapp.use(). - NestJS Guards handle authentication and authorization checks before a route handler runs.
- Interceptors wrap route handlers for cross-cutting concerns like logging, response transformation, and caching.
- Pipes handle input validation and transformation (e.g., parsing route params, validating DTOs).
Validation
- We use the
class-validatorandclass-transformerlibraries with NestJS'sValidationPipeto declaratively validate incoming request bodies using DTOs (Data Transfer Objects).
- Apply
@IsString(),@IsNumber(),@IsEnum(), and other decorators on DTO class properties for automatic validation.
Authentication & Authorization
- NestJS Guards implement the
CanActivateinterface and are used to protect routes. - In the Courier Integration Service we use Clerk as our third-party authentication provider via a custom
ClerkAuthGuardthat implementsCanActivate. The guard verifies the incoming request's session token against Clerk's backend SDK before allowing access. - Apply the guard on a per-controller or per-route basis using
@UseGuards(ClerkAuthGuard). In the CIS, every protected controller is guarded at the controller class level. - Clerk requires
CLERK_PUBLISHABLE_KEYandCLERK_SECRET_KEYto be set in your environment — these are loaded by@nestjs/configand validated at startup.
Check out the Clerk Documentation for more detail on the backend SDK and token verification.
Configuration & Environment
- The
@nestjs/configmodule provides aConfigServicefor type-safe access to environment variables, supporting.envfiles and custom configuration namespaces.
Error Handling
- NestJS has built-in Exception Filters that catch errors and transform them into structured HTTP responses.
- Throw built-in exceptions like
NotFoundException,BadRequestException, orUnauthorizedExceptiondirectly from services or controllers. - Create custom exception filters by implementing the
ExceptionFilterinterface for fine-grained error handling.
Testing
NestJS is designed with testability in mind and the CIS test suite reflects this thoroughly. Tests live inside __tests__/ directories co-located with their modules and are discovered via the *.spec.ts glob pattern.
Test runner & toolchain
- Jest is the test runner (
npm run test). Additional scripts:test:watch,test:cov(coverage), andtest:e2e. - ts-jest transpiles TypeScript spec files on the fly — no separate build step required.
@nestjs/testingprovidesTest.createTestingModule()to spin up an isolated NestJS module context per test suite.
Unit test pattern
Each spec bootstraps a minimal TestingModule that includes only the controller or service under test, with all dependencies replaced by jest.fn() mocks:
Handling Clerk auth in tests
Because every production controller uses @UseGuards(ClerkAuthGuard), tests call .overrideGuard(ClerkAuthGuard).useValue({ canActivate: () => true }) on the module builder to short-circuit the guard without needing real Clerk credentials.
Fake timers
The CIS uses @nestjs/schedule for batch-flush timeouts. Tests control this with Jest's fake timer API:
Spying on private logger
NestJS controllers expose a Logger instance as a private field. Tests reach it directly to assert on log output:
Cleanup
jest.clearAllMocks() is called in afterEach to reset call counts and return values between tests, preventing state leakage.
In-memory database (integration tests)
For tests that need real MongoDB behaviour, the project ships mongodb-memory-server, which spins up an ephemeral in-process MongoDB instance — no external database required.
Performance & Deployment
- NestJS supports Fastify as an alternative HTTP adapter for higher throughput.
- Applications are built with
nest buildand deployed as standard Node.js processes. - Works seamlessly with Docker and containerized deployment strategies.
Helpful Links
- NestJS Official Documentation: https://docs.nestjs.com
- NestJS Controllers: https://docs.nestjs.com/controllers
- NestJS Providers & Services: https://docs.nestjs.com/providers
- NestJS Modules: https://docs.nestjs.com/modules
- NestJS Guards (Auth): https://docs.nestjs.com/guards
- NestJS Pipes (Validation): https://docs.nestjs.com/pipes
- NestJS Exception Filters: https://docs.nestjs.com/exception-filters
- NestJS Config Module: https://docs.nestjs.com/techniques/configuration
- NestJS Testing: https://docs.nestjs.com/fundamentals/testing
