ValidationPipe

⭐ Interview Importance: LOW
⏱️ Revision Time: 7 min

The ValidationPipe is the workhorse of the NestJS validation system. It automatically intercepts incoming requests, reads the DTO rules, and enforces them.

Overview

While you can use ValidationPipe on a per-route basis, it is almost universally applied globally in a NestJS application.

It acts as an impenetrable shield for your application. If a client sends a JSON body that doesn’t perfectly match the rules defined in your DTO decorators (from class-validator), the pipe intercepts the request, blocks it from reaching your controller, and automatically sends a beautifully formatted 400 Bad Request response detailing exactly what went wrong.

Key Concepts

  • class-validator integration: The pipe relies entirely on metadata generated by class-validator decorators (like @IsString()).
  • class-transformer integration: The pipe relies on class-transformer to convert the raw JSON string into a real instance of your DTO class so that the validation rules can actually be run.
  • Auto-Transformation: The pipe can be configured to automatically cast simple primitive types (strings to numbers/booleans).

Code Examples

Global Setup (The Gold Standard)

This is the recommended configuration for almost every NestJS API.

// main.ts
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { AppModule } from './app.module';

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

  app.useGlobalPipes(
    new ValidationPipe({
      // 1. whitelist: true
      // Automatically strip out any properties from the incoming JSON 
      // that do NOT have a decorator in the DTO. (Security feature)
      whitelist: true,

      // 2. forbidNonWhitelisted: true
      // Instead of silently stripping unknown properties, throw an error 
      // if the user sends unexpected data.
      forbidNonWhitelisted: true,

      // 3. transform: true
      // Automatically transforms the plain JSON payload into an actual 
      // instance of the DTO class.
      transform: true,

      // 4. transformOptions: { enableImplicitConversion: true }
      // Magically converts query parameters (which are always strings) 
      // into numbers or booleans based on the TypeScript type!
      transformOptions: {
        enableImplicitConversion: true,
      },
    }),
  );

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

The Resulting Error

If a client sends invalid data, the ValidationPipe automatically generates a response like this:

{
  "statusCode": 400,
  "message": [
    "email must be an email",
    "password must be longer than or equal to 8 characters"
  ],
  "error": "Bad Request"
}

Best Practices

  • Always use whitelist: true: This prevents “Mass Assignment” vulnerabilities. If your DTO doesn’t define an isAdmin property, but the user maliciously sends { "isAdmin": true } in the JSON body, whitelist: true ensures that property is silently deleted before the data reaches your controller.
  • Install Dependencies: The ValidationPipe is built into NestJS, but it will throw runtime errors if you forget to install its underlying engines. You must always run npm install class-validator class-transformer.