We use cookies to enhance your experience on the site
CodeWorlds

ValidationPipe — The Automatic Control Station

You've met the guards (class-validator decorators) and you know how to describe validation rules in DTOs. But who actually activates these guards? The answer is ValidationPipe — it's like the chief control officer standing at the gate and coordinating the work of all the guards.

What Is ValidationPipe?

ValidationPipe is a built-in NestJS pipe that automatically:

  1. Transforms incoming data into an instance of the DTO class
  2. Runs all class-validator decorators
  3. Returns a 400 Bad Request error if validation fails

Global Configuration in main.ts

The most convenient way is to enable ValidationPipe globally for the entire application:

1// main.ts - The Empire's Main Gate
2import { NestFactory } from '@nestjs/core';
3import { ValidationPipe } from '@nestjs/common';
4import { AppModule } from './app.module';
5
6async function bootstrap() {
7  const app = await NestFactory.create(AppModule);
8
9  // Setting up global gate guard
10  app.useGlobalPipes(new ValidationPipe());
11
12  await app.listen(3000);
13}
14bootstrap();

ValidationPipe Configuration Options

ValidationPipe accepts an options object that allows you to customize guard behavior:

whitelist — only pass known fields

1app.useGlobalPipes(new ValidationPipe({
2  whitelist: true,
3}));

With the

whitelist: true
option, the pipe automatically removes all fields that don't have validation decorators in the DTO. It's like a guard confiscating suspicious items at the gate:

1// DTO only allows 'name' and 'age'
2export class CreateLegionaryDto {
3  @IsString()
4  name: string;
5
6  @IsNumber()
7  age: number;
8}
9
10// A request comes in with an extra field:
11// { name: "Marcus", age: 25, isAdmin: true }
12
13// With whitelist: true, the 'isAdmin' field is removed
14// Controller receives: { name: "Marcus", age: 25 }

forbidNonWhitelisted — reject requests with unknown fields

1app.useGlobalPipes(new ValidationPipe({
2  whitelist: true,
3  forbidNonWhitelisted: true,
4}));

This is an even stricter option — instead of removing unknown fields, the server returns an error. The guard doesn't confiscate items but immediately denies entry:

1// { name: "Marcus", age: 25, isAdmin: true }
2// Response: 400 Bad Request
3// "property isAdmin should not exist"

transform — automatic type conversion

1app.useGlobalPipes(new ValidationPipe({
2  transform: true,
3}));

URL parameters always arrive as strings. With the

transform: true
option, the pipe automatically converts them to the appropriate types:

1@Get(':id')
2findOne(@Param('id') id: number) {
3  // Without transform: id is a string "42"
4  // With transform: id is a number 42
5  console.log(typeof id); // "number"
6}

Route-Level Usage

You can also use ValidationPipe on a specific endpoint instead of globally:

1@Post()
2@UsePipes(new ValidationPipe({ whitelist: true }))
3createLegionary(@Body() dto: CreateLegionaryDto) {
4  return this.service.create(dto);
5}

Or on a specific parameter:

1@Post()
2createLegionary(
3  @Body(new ValidationPipe({ whitelist: true })) dto: CreateLegionaryDto,
4) {
5  return this.service.create(dto);
6}

Recommended Production Configuration

Here is the configuration used by most NestJS projects:

1app.useGlobalPipes(new ValidationPipe({
2  whitelist: true,
3  forbidNonWhitelisted: true,
4  transform: true,
5  transformOptions: {
6    enableImplicitConversion: true,
7  },
8}));

This configuration ensures:

  • Removal of unknown fields (
    whitelist
    )
  • Rejection of requests with unknown fields (
    forbidNonWhitelisted
    )
  • Automatic type conversion (
    transform
    )
  • Implicit conversion based on TypeScript types (
    enableImplicitConversion
    )

ValidationPipe is the foundation of your API's security. Without it, class-validator decorators are like guards without a commander — they don't know when to act!

Go to CodeWorlds