How to Use Pipes in NestJS: Validation and Transformation
pipes are classes that transform or validate data before it reaches your route handler. You use them by applying the @UsePipes() decorator at the method or controller level or by implementing the PipeTransform interface for custom logic.Syntax
A pipe in NestJS is a class that implements the PipeTransform interface with a transform() method. You apply pipes using the @UsePipes() decorator on controllers or route handlers. Pipes receive the input value and metadata, then return the transformed value or throw an error if validation fails.
- Pipe class: Implements
PipeTransformwithtransform(value, metadata). - @UsePipes(): Decorator to attach pipes to routes or controllers.
- Built-in pipes: NestJS provides pipes like
ValidationPipeandParseIntPipe.
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common'; @Injectable() export class CustomPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { // transform or validate value if (!value) { throw new BadRequestException('Value is required'); } return value; } } // Usage in controller import { Controller, Get, Query, UsePipes } from '@nestjs/common'; @Controller('items') @UsePipes(CustomPipe) // applies to all routes in this controller export class ItemsController { @Get() findAll(@Query('id') id: string) { return `Item id is ${id}`; } }
Example
This example shows how to use the built-in ParseIntPipe to automatically convert a query parameter to a number and validate it. If the parameter is not a number, NestJS returns a 400 error.
import { Controller, Get, Query, ParseIntPipe } from '@nestjs/common'; @Controller('products') export class ProductsController { @Get() getProduct(@Query('id', ParseIntPipe) id: number) { return `Product id is ${id}`; } }
Common Pitfalls
- Forgetting to add
@Injectable()to custom pipes causes NestJS to not recognize them. - Applying pipes globally without care can cause unexpected validation errors.
- Using pipes only validates or transforms input but does not handle business logic.
- Not returning the transformed value from
transform()will break the flow.
import { PipeTransform, Injectable, BadRequestException } from '@nestjs/common'; // Wrong: Missing @Injectable() export class MissingInjectablePipe implements PipeTransform { transform(value: any) { return value; } } // Right: @Injectable() export class CorrectPipe implements PipeTransform { transform(value: any) { if (!value) { throw new BadRequestException('Value required'); } return value; } }
Quick Reference
Use pipes to validate and transform data before it reaches your route handlers. Apply pipes with @UsePipes() or inline on parameters. Use built-in pipes like ValidationPipe for DTO validation and ParseIntPipe for type conversion. Always return the transformed value and decorate custom pipes with @Injectable().
| Pipe | Purpose | Usage Example |
|---|---|---|
| ValidationPipe | Validates DTOs using class-validator | @UsePipes(new ValidationPipe()) |
| ParseIntPipe | Converts string to number | @Query('id', ParseIntPipe) id: number |
| CustomPipe | Custom validation or transformation | Create class implementing PipeTransform |