0
0
NestjsHow-ToBeginner ยท 3 min read

How to Use Pipes in NestJS: Validation and Transformation

In NestJS, 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 PipeTransform with transform(value, metadata).
  • @UsePipes(): Decorator to attach pipes to routes or controllers.
  • Built-in pipes: NestJS provides pipes like ValidationPipe and ParseIntPipe.
typescript
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.

typescript
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}`;
  }
}
Output
If you call GET /products?id=5, the response is: "Product id is 5" If you call GET /products?id=abc, the response is a 400 Bad Request error with message: "Validation failed (numeric string is expected)"
โš ๏ธ

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.
typescript
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().

PipePurposeUsage Example
ValidationPipeValidates DTOs using class-validator@UsePipes(new ValidationPipe())
ParseIntPipeConverts string to number@Query('id', ParseIntPipe) id: number
CustomPipeCustom validation or transformationCreate class implementing PipeTransform
โœ…

Key Takeaways

Pipes in NestJS transform or validate data before it reaches route handlers.
Use @UsePipes() decorator to apply pipes at controller or method level.
Always return the transformed value from the transform() method.
Use built-in pipes like ValidationPipe and ParseIntPipe for common needs.
Custom pipes must be decorated with @Injectable() to work properly.