Pipes in NestJS help check if the data coming into your app is correct and change it into the right format. This keeps your app safe and working well.
Why pipes transform and validate input in NestJS
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common'; @Injectable() export class ExamplePipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { // Validate or transform the value if (typeof value !== 'string') { throw new BadRequestException('Invalid input'); } return value.toUpperCase(); } }
The transform method runs automatically on input data.
Throwing an exception stops the request and sends an error response.
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common'; @Injectable() export class ParseIntPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { const val = parseInt(value, 10); if (isNaN(val)) { throw new BadRequestException('Validation failed'); } return val; } }
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common'; @Injectable() export class TrimPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { if (typeof value === 'string') { return value.trim(); } return value; } }
This example shows a controller that uses a pipe to check if the query parameter 'id' is a number. If not, it sends an error. If yes, it returns a message with the id.
import { Controller, Get, Query, UsePipes, PipeTransform, Injectable, BadRequestException, ArgumentMetadata } from '@nestjs/common'; @Injectable() class ParseIntPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { const val = parseInt(value, 10); if (isNaN(val)) { throw new BadRequestException('Validation failed: Not a number'); } return val; } } @Controller('items') export class ItemsController { @Get() @UsePipes(new ParseIntPipe()) getItem(@Query('id') id: string) { return `Item id is ${id}`; } }
Pipes run before your route handler, so they catch bad data early.
You can reuse pipes in many places to keep your code DRY (Don't Repeat Yourself).
Always provide clear error messages to help users fix their input.
Pipes check and change input data before your app uses it.
They help keep your app safe and error-free.
Use pipes to make your code cleaner and easier to maintain.
Practice
Solution
Step 1: Understand the role of pipes in NestJS
Pipes are designed to process input data by validating and transforming it before it reaches the application logic.Step 2: Compare options with pipe functionality
Only To check and change input data before the app uses it describes this behavior correctly; other options relate to unrelated tasks.Final Answer:
To check and change input data before the app uses it -> Option CQuick Check:
Pipes = Validate and transform input [OK]
- Confusing pipes with UI styling tools
- Thinking pipes manage database or HTTP responses only
- Ignoring pipes' role in validation
Solution
Step 1: Recall NestJS pipe syntax for method parameters
To apply a pipe, you pass an instance of the pipe class inside the decorator, e.g., @Body(new ValidationPipe()).Step 2: Analyze each option's syntax
@Body(new ValidationPipe()) inputData: CreateDto correctly instantiates and passes the ValidationPipe to @Body(). The other options either pass the class without instantiation, misplace the pipe, or confuse the order.Final Answer:
@Body(new ValidationPipe()) inputData: CreateDto -> Option BQuick Check:
Use new PipeClass() inside decorator [OK]
- Instantiating pipe with new inside decorator
- Placing pipe after parameter name
- Confusing decorator and parameter order
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
@Injectable()
export class ToNumberPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
const val = Number(value);
if (isNaN(val)) {
throw new Error('Validation failed');
}
return val;
}
}What will be the output if the controller method receives the string
'42' as input and uses this pipe?Solution
Step 1: Understand the pipe's transform method
The pipe converts the input value to a number using Number(value). If conversion fails, it throws an error.Step 2: Apply the pipe to input '42'
Number('42') returns 42 (a number), which is valid, so no error is thrown and 42 is returned.Final Answer:
The number 42 -> Option AQuick Check:
String '42' converts to number 42 [OK]
- Thinking the pipe returns the original string
- Assuming an error is thrown for numeric strings
- Confusing string and number types
transform(value: any) {
const num = parseInt(value);
if (!num) {
throw new Error('Invalid number');
}
return num;
}What is the bug in this pipe when input is
'0'?Solution
Step 1: Analyze the condition !num with input '0'
parseInt('0') returns 0, but !0 is true in JavaScript, so the error is thrown incorrectly.Step 2: Identify the bug cause
The check should explicitly test for NaN, not falsy values, to avoid rejecting valid 0.Final Answer:
It throws an error incorrectly because !num is true for 0 -> Option AQuick Check:
Falsy check fails for 0, use isNaN instead [OK]
- Using !num to check invalid numbers
- Ignoring 0 as a valid number
- Not testing for NaN explicitly
Solution
Step 1: Understand pipe responsibilities
A pipe should both validate and transform input if needed, keeping logic together.Step 2: Evaluate options for combining validation and transformation
In the transform method, first check email format with regex, then return value.toLowerCase() correctly validates email format and then transforms to lowercase inside the pipe. Transforming to lowercase only skips validation, separating validation and transformation across controller and pipe splits the logic, and throwing an error if already lowercase is illogical.Final Answer:
In the transform method, first check email format with regex, then return value.toLowerCase() -> Option DQuick Check:
Validate then transform inside pipe [OK]
- Separating validation and transformation outside pipe
- Skipping validation step
- Throwing errors for valid inputs
Ready to prove it?
Pass the test and this pattern moves unknown
