Pipes: Transform & Validate
Pipes: Transform & Validate
A pipe sits between the incoming request and your handler, doing one of two jobs: transformation (convert input to the desired form) or validation (check input and throw if it is invalid). The ValidationPipe from the previous lesson is just one built-in pipe — now let us understand the mechanism.
Built-in pipes
NestJS ships several ready-to-use pipes. The most common convert string route params into typed values:
Other built-ins include ParseUUIDPipe, ParseBoolPipe, ParseArrayPipe, ParseEnumPipe, and DefaultValuePipe.
ParseIntPipe turns '42' into the number 42 — and rejects 'abc' with a 400 before your handler runs.
Where pipes can be applied
- Parameter-level — on a single
@Param()/@Body()(most precise). - Method-level — with
@UsePipes()on a handler. - Global —
app.useGlobalPipes()inmain.ts(applies everywhere).
Writing a custom pipe
A custom pipe implements PipeTransform and a single transform(value, metadata) method. Whatever it returns becomes the handler's argument; whatever it throws becomes the error response:
The metadata argument
The second parameter tells the pipe what it is processing — the type (body, query, param), the expected metatype, and the parameter name. This is how a generic pipe like ValidationPipe knows which DTO class to validate against:
Summary
Pipes transform or validate inputs before they reach your handler. Use built-in pipes like ParseIntPipe to convert and guard route params, and write custom pipes by implementing PipeTransform.transform(). The metadata argument lets generic pipes inspect what they are processing. Pipes can be bound at parameter, method, or global level. Next: middleware, which runs even earlier in the lifecycle.