NestJS

Lesson 03

DTO validation pipes

Validate request DTOs at the NestJS boundary before controller methods receive untrusted input.

Good Code

main.ts
import { ValidationPipe } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // The global pipe rejects unknown fields before controllers run.
  app.useGlobalPipes(
    new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }),
  );

  await app.listen(3000);
}
bootstrap();

Bad Code

reviews.controller.ts
import { Body, Controller, Post } from "@nestjs/common";

@Controller("reviews")
export class ReviewsController {
  @Post()
  create(@Body() body: any) {
    // Validation is scattered inside route code and misses extra fields.
    if (!body.title) throw new Error("title is required");
    return this.reviews.create(body);
  }
}

Review Notes

What to review

Good Code

The good version applies ValidationPipe at the application boundary, so DTO rules run before controller methods.

Bad Code

The bad version validates one field by hand inside the route. Extra request fields can still pass through to the service.

Takeaways

  • A controller should receive data that already passed DTO validation and transformation rules.