NestJS Architecture

⭐ Interview Importance: HIGH
⏱️ Revision Time: 13 min

NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications.

Overview

NestJS architecture is heavily inspired by Angular. It provides an out-of-the-box application architecture which allows developers to create highly testable, scalable, loosely coupled, and easily maintainable applications.

At its core, NestJS abstracts the underlying HTTP frameworks (like Express or Fastify) and provides a higher-level API, leveraging modern JavaScript/TypeScript features like Decorators and robust Dependency Injection.

Key Concepts

  • Modules: The building blocks of a Nest application, used to organize code into cohesive blocks of capabilities.
  • Controllers: Responsible for handling incoming requests and returning responses to the client.
  • Providers: The core mechanism of Dependency Injection (DI) in Nest. Services, repositories, factories, and helpers are all treated as providers.
  • Dependency Injection (DI): A design pattern used to implement IoC (Inversion of Control), allowing the creation of dependent objects outside of a class and providing them to a class.

The Request Lifecycle

  1. Middleware: Executes first. Good for logging, authentication headers parsing.
  2. Guards: Determine whether a given request will be handled by the route handler. (Authentication/Authorization)
  3. Interceptors (pre-controller): Can bind extra logic before the route handler is executed.
  4. Pipes: Transform or validate the input data before it hits the route handler.
  5. Controller Handler: The actual business logic execution (usually delegates to a Service).
  6. Interceptors (post-controller): Transform the response returned from the route handler.
  7. Exception Filters: Catch unhandled exceptions and format the error response.

Code Examples

A Basic NestJS App Entry Point (main.ts)

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  // NestFactory creates an instance of the Nest application
  const app = await NestFactory.create(AppModule);
  
  // Start the server on port 3000
  await app.listen(3000);
  console.log('Application is running on: http://localhost:3000');
}
bootstrap();

Best Practices

  • Embrace Modularity: Divide your application into feature modules (e.g., UsersModule, OrdersModule) rather than grouping by file type (all controllers together, all services together).
  • Keep Controllers Lean: Controllers should only handle HTTP routing and request/response parsing. Delegate heavy business logic to Services (Providers).
  • Use DTOs: Always use Data Transfer Objects (Classes) along with ValidationPipes to strictly validate incoming request payloads.