Skip to main content

What is a Pipe?

1. What a Pipe is in NestJS

A Pipe is a class that implements the PipeTransform interface and has a transform(value, metadata) method.

Pipes:

  • accept input data (e.g. req.body, req.params, req.query);
  • can transform or validate it;
  • return the transformed value, which the controller's method then receives;
  • or throw an error if the data is invalid.

A simple pipe example:

javascript
import { PipeTransform, Injectable } from '@nestjs/common'; @Injectable() export class UpperCasePipe implements PipeTransform { transform(value: any) { return typeof value === 'string' ? value.toUpperCase() : value; } }

Now, if you apply it to a controller parameter, the value gets converted to uppercase automatically.

2. Where Pipes are applied

You can use Pipes at three levels:

LevelExampleScope
Parameter@Body(new ValidationPipe())Only one parameter
Method@UsePipes(ValidationPipe)Every parameter of the method
Controller / Globallyapp.useGlobalPipes(new ValidationPipe())The whole application

An example at the parameter level:

javascript
@Get(':id') getUser(@Param('id', ParseIntPipe) id: number) { // id has already been converted to a number automatically return this.userService.findById(id); }

If a user calls /users/123, then id inside the function is the number 123, not the string '123'.

If the value can't be converted, Nest throws a BadRequestException.

3. Types of pipes

TypePurposeExample
Transformation pipesTransform input data (string → number, trim, etc.)ParseIntPipe, ParseBoolPipe
Validation pipesCheck that data is correctValidationPipe (with class-validator)
Custom pipesAny custom logic (e.g. sanitize, normalize)SlugifyPipe, TrimPipe

4. The most commonly used one, ValidationPipe

NestJS provides a built-in ValidationPipe that works with the class-validator and class-transformer packages.

Example:

javascript
import { IsString, IsEmail, Length } from 'class-validator'; export class CreateUserDto { @IsString() @Length(3, 30) name: string; @IsEmail() email: string; }
javascript
@Post() createUser(@Body(new ValidationPipe()) dto: CreateUserDto) { return this.userService.create(dto); }

Now Nest automatically:

  1. Converts the JSON from the request body into a CreateUserDto instance;
  2. Checks the fields via class-validator;
  3. Returns a 400 Bad Request with a detailed error description if validation fails.

5. A global ValidationPipe example

Usually enabled once, in main.ts:

javascript
import { ValidationPipe } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes( new ValidationPipe({ transform: true, // automatically coerces types (string → number) whitelist: true, // strips fields not present in the DTO forbidNonWhitelisted: true, // throws on extra fields }), ); await app.listen(3000); } bootstrap();

Now every controller's input data gets validated without naming a Pipe explicitly.

6. A custom Pipe example for checking an id

javascript
import { PipeTransform, BadRequestException } from '@nestjs/common'; export class ParseObjectIdPipe implements PipeTransform<string> { transform(value: string) { const isValid = /^[0-9a-fA-F]{24}$/.test(value); if (!isValid) { throw new BadRequestException('Invalid MongoDB ObjectId'); } return value; } }

Usage:

javascript
@Get(':id') getUser(@Param('id', new ParseObjectIdPipe()) id: string) { return this.userService.findById(id); }

7. When Pipes are worth using

TaskSolution
Type conversion (string → number)ParseIntPipe
DTO validationValidationPipe
Cleaning up data (trim, lowercase)A custom pipe
Checking parametersA custom pipe (CheckUuidPipe, ParseObjectIdPipe)
Transforming input dataTransformPipe, NormalizePipe

8. Summary

A Pipe in NestJS is a mechanism that performs:

  • validation of input data,
  • type conversion,
  • normalization of data before it reaches the controller.

Pipes:

  • Implement the PipeTransform interface;
  • Run before the handler is called;
  • Can be local, method-level, or global;
  • Are commonly used for DTO validation and typing input data.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.