What is a Pipe?
1. What a Pipe is in NestJS
A Pipe is a class that implements the
PipeTransforminterface and has atransform(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:
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:
| Level | Example | Scope |
|---|---|---|
| Parameter | @Body(new ValidationPipe()) | Only one parameter |
| Method | @UsePipes(ValidationPipe) | Every parameter of the method |
| Controller / Globally | app.useGlobalPipes(new ValidationPipe()) | The whole application |
An example at the parameter level:
@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
| Type | Purpose | Example |
|---|---|---|
| Transformation pipes | Transform input data (string → number, trim, etc.) | ParseIntPipe, ParseBoolPipe |
| Validation pipes | Check that data is correct | ValidationPipe (with class-validator) |
| Custom pipes | Any 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:
import { IsString, IsEmail, Length } from 'class-validator';
export class CreateUserDto {
@IsString()
@Length(3, 30)
name: string;
@IsEmail()
email: string;
}@Post()
createUser(@Body(new ValidationPipe()) dto: CreateUserDto) {
return this.userService.create(dto);
}Now Nest automatically:
- Converts the JSON from the request body into a
CreateUserDtoinstance; - Checks the fields via
class-validator; - Returns a
400 Bad Requestwith a detailed error description if validation fails.
5. A global ValidationPipe example
Usually enabled once, in main.ts:
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
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:
@Get(':id')
getUser(@Param('id', new ParseObjectIdPipe()) id: string) {
return this.userService.findById(id);
}7. When Pipes are worth using
| Task | Solution |
|---|---|
| Type conversion (string → number) | ParseIntPipe |
| DTO validation | ValidationPipe |
| Cleaning up data (trim, lowercase) | A custom pipe |
| Checking parameters | A custom pipe (CheckUuidPipe, ParseObjectIdPipe) |
| Transforming input data | TransformPipe, 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
PipeTransforminterface; - 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 readyA concise answer to help you respond confidently on this topic during an interview.