Skip to main content

NestJS

1. Core Concepts

1.1. Module

Organizes code into reusable units with controllers and providers.

app.module.ts
import { Module } from "@nestjs/common";
import { CatsController } from "./cats.controller";
import { CatsService } from "./cats.service";

@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class AppModule {}

1.2. Controller

Handles HTTP requests and defines routes.

cats.controller.ts
import { Controller, Get, Param } from "@nestjs/common";
import { CatsService } from "./cats.service";

@Controller("cats")
export class CatsController {
constructor(private readonly catsService: CatsService) {}

@Get(":id")
findOne(@Param("id") id: string): string {
return this.catsService.findOne(id);
}
}

1.3. Service (Provider)

Contains business logic, injectable into controllers.

cats.service.ts
import { Injectable } from "@nestjs/common";

@Injectable()
export class CatsService {
findOne(id: string): string {
return `Cat with id ${id}`;
}
}

1.4. Middleware

Processes requests before reaching controllers.

logger.middleware.ts
import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response, NextFunction } from "express";

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log("Request:", req.method, req.url);
next();
}
}

1.5. Guard

Protects routes by checking permissions.

auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";

@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
return request.headers["api_key"] === "MY_API_KEY";
}
}

1.6. Interceptor

Transforms request/response data.

transform.interceptor.ts
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from "@nestjs/common";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";

@Injectable()
export class TransformInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(map((data) => ({ data })));
}
}

1.7. Pipe

Validates or transforms input data.

create-cat.dto.ts
import { IsString, IsInt } from "class-validator";

export class CreateCatDto {
@IsString()
name: string;

@IsInt()
age: number;
}
cats.controller.ts
import { Controller, Post, Body, ValidationPipe } from "@nestjs/common";
import { CreateCatDto } from "./create-cat.dto";

// You can add provider APP_PIPE (@nestjs/core) with new ValidationPipe({ whitelist: true }) on AppModule
@Controller("cats")
export class CatsController {
@Post()
create(@Body(ValidationPipe) createCatDto: CreateCatDto) {
return createCatDto;
}
}
PackagePurposeIntegration Example
class-validatorValidates DTOsUse with ValidationPipe in controllers.
passportAuthentication (JWT, OAuth2)Use @nestjs/passport for strategies.
swaggerGenerates API docsUse @nestjs/swagger to annotate APIs.
typeormORM for SQL databasesUse @nestjs/typeorm for DB integration.
nestjs/configManages app configurationUse @nestjs/config to load .env files.

Config Example:

app.module.ts
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";

@Module({
imports: [ConfigModule.forRoot({ isGlobal: true })],
})
export class AppModule {}

3. Advanced Topics

3.1. Microservices

Enables distributed systems with message brokers.

app.module.ts
import { Module } from "@nestjs/common";
import { ClientsModule, Transport } from "@nestjs/microservices";

@Module({
imports: [
ClientsModule.register([
{
name: "BOOKSTORE_SERVICE",
transport: Transport.TCP,
options: { host: "localhost", port: 3000 },
},
]),
],
})
export class AppModule {}

Common Issues & Solutions:

  • Scaling: Use Docker/Kubernetes for horizontal scaling.
  • Connection Issues: Implement retry mechanisms and heartbeats.
  • Data Consistency: Use event-driven patterns (e.g., Kafka).

3.2. WebSocket

Supports real-time communication.

chat.gateway.ts
import {
WebSocketGateway,
SubscribeMessage,
WebSocketServer,
} from "@nestjs/websockets";
import { Server } from "socket.io";

@WebSocketGateway({ cors: { origin: "*" } })
export class ChatGateway {
@WebSocketServer() server: Server;

@SubscribeMessage("chat")
handleEvent(@MessageBody() payload: any): any {
this.server.emit("chat", payload);
return payload;
}
}

Common Issues & Solutions:

  • Scaling: Use Redis pub/sub for distributed WebSocket.
  • Dropped Connections: Implement heartbeats.
  • Security: Authenticate clients with tokens.

3.3. Security

Secures APIs with authentication and protections.

auth.module.ts
import { Module } from "@nestjs/common";
import { PassportModule } from "@nestjs/passport";
import { JwtModule } from "@nestjs/jwt";

@Module({
imports: [
PassportModule.register({ defaultStrategy: "jwt" }),
JwtModule.register({
secret: "secretKey",
signOptions: { expiresIn: "60m" },
}),
],
})
export class AuthModule {}

Common Issues & Solutions:

  • Permission Errors: Use role-based access control (RBAC).
  • Security Holes: Apply Helmet and input validation.
  • Rate Limiting: Use express-rate-limit for API protection.

4. System Architecture Diagram

References