📖 Scenario: You are building a NestJS backend that accepts file uploads. To keep your app safe and clean, you want to check that uploaded files meet certain rules before processing them.Imagine you run a photo sharing app. You want to accept only image files and limit their size to 1MB.
🎯 Goal: Create a custom file validation pipe in NestJS that checks if the uploaded file is an image and is smaller than 1MB.This pipe will help your app reject bad files early and keep your backend safe.
📋 What You'll Learn
Create a file validation pipe class named FileValidationPipe
Add a configuration variable maxFileSize set to 1_000_000 (1MB)
Implement the transform method to check file mimetype and size
Throw a BadRequestException if file is not an image or too large
💡 Why This Matters
🌍 Real World
File validation pipes help backend apps securely accept user uploads by checking file types and sizes before processing.
💼 Career
Backend developers often write custom pipes in NestJS to validate and transform incoming data, improving app security and reliability.
Progress0 / 4 steps
1
Create the FileValidationPipe class
Create a class called FileValidationPipe that implements PipeTransform from @nestjs/common. Import PipeTransform and BadRequestException from @nestjs/common.
NestJS
Hint
Start by importing PipeTransform and BadRequestException. Then create a class named FileValidationPipe that implements PipeTransform. Add a transform method that returns the input value for now.
2
Add maxFileSize configuration
Inside the FileValidationPipe class, add a readonly property called maxFileSize and set it to 1_000_000 (1MB).
NestJS
Hint
Add a property maxFileSize inside the class and set it to 1_000_000. Use readonly to prevent changes.
3
Implement file type and size checks in transform
In the transform method, check if value has a mimetype starting with 'image/' and a size less than or equal to this.maxFileSize. If either check fails, throw a BadRequestException with the message 'Invalid file type or file too large'. Otherwise, return value.
NestJS
Hint
Use an if statement to check if value is missing, or if value.mimetype does not start with 'image/', or if value.size is greater than this.maxFileSize. Throw BadRequestException if any check fails.
4
Export and finalize the FileValidationPipe
Make sure the FileValidationPipe class is exported using export keyword so it can be used in other parts of the NestJS app.
NestJS
Hint
Check that the class declaration starts with export so it can be imported elsewhere.
Practice
(1/5)
1. What is the main purpose of a FileValidationPipe in NestJS?
easy
A. To upload files to a cloud storage service
B. To convert files into JSON format automatically
C. To check uploaded files for type, size, and presence before processing
D. To compress files before saving them
Solution
Step 1: Understand the role of validation pipes in NestJS
Validation pipes are used to check and validate incoming data before it reaches the controller logic.
Step 2: Apply this to file uploads
A FileValidationPipe specifically checks uploaded files for correct type, size, and presence to prevent bad data.
Final Answer:
To check uploaded files for type, size, and presence before processing -> Option C
Quick Check:
File validation = check file properties [OK]
Hint: Validation pipes check data early to keep apps safe [OK]
Common Mistakes:
Thinking pipes upload or transform files
Confusing validation with file storage
Assuming pipes compress files automatically
2. Which of the following is the correct way to apply a file validation pipe to a file upload in a NestJS controller?
easy
A. @UsePipes(new FileValidationPipe()) uploadFile(@UploadedFile() file: Express.Multer.File) {}
B. @UseGuards(new FileValidationPipe()) uploadFile(@UploadedFile() file: Express.Multer.File) {}
C. @UseFilters(new FileValidationPipe()) uploadFile(@UploadedFile() file: Express.Multer.File) {}
D. @UseInterceptors(new FileValidationPipe()) uploadFile(@UploadedFile() file: Express.Multer.File) {}
Solution
Step 1: Identify the correct decorator for validation pipes
In NestJS, validation pipes are applied using the @UsePipes() decorator.
Step 2: Match the usage with file upload
The FileValidationPipe is a pipe, so it must be passed inside @UsePipes() to validate the uploaded file.
Final Answer:
@UsePipes(new FileValidationPipe()) uploadFile(@UploadedFile() file: Express.Multer.File) {} -> Option A
Quick Check:
Validation pipe = @UsePipes() [OK]
Hint: Use @UsePipes() for validation pipes, not guards or filters [OK]
Common Mistakes:
Using @UseGuards or @UseFilters instead of @UsePipes
Applying pipes without instantiating them
Confusing interceptors with pipes
3. Given this pipe code snippet, what will happen if a user uploads a file larger than 1MB?
export class FileValidationPipe implements PipeTransform {
transform(file: Express.Multer.File) {
if (!file) throw new BadRequestException('File is required');
if (file.size > 1_000_000) throw new BadRequestException('File too large');
return file;
}
}
medium
A. The pipe ignores the size and processes the file
B. The pipe accepts the file and returns it
C. The pipe throws a NotFoundException
D. The pipe throws a BadRequestException with message 'File too large'
Solution
Step 1: Analyze the size check in the transform method
The pipe checks if file.size is greater than 1,000,000 bytes (1MB).
Step 2: Understand the exception thrown on size violation
If the file is too large, it throws BadRequestException('File too large'), stopping the request.
Final Answer:
The pipe throws a BadRequestException with message 'File too large' -> Option D
Quick Check:
File size > 1MB = BadRequestException [OK]
Hint: Check exception messages in transform() for validation errors [OK]
Common Mistakes:
Assuming the pipe accepts large files
Confusing BadRequestException with NotFoundException
Ignoring the file presence check
4. Identify the error in this file validation pipe code:
export class FileValidationPipe implements PipeTransform {
transform(file: Express.Multer.File) {
if (!file) throw new BadRequestException('File is required');
if (file.mimetype !== 'image/png' || file.mimetype !== 'image/jpeg') {
throw new BadRequestException('Invalid file type');
}
return file;
}
}
medium
A. The mimetype check always throws because of incorrect logical operator
B. The file presence check is missing
C. The pipe does not return the file
D. The exception type is incorrect
Solution
Step 1: Examine the mimetype condition
The condition uses || (OR) between two checks: file.mimetype !== 'image/png' OR file.mimetype !== 'image/jpeg'.
Step 2: Understand why this always triggers
Because a file cannot be both 'image/png' and 'image/jpeg' at the same time, one of these will always be true, causing the exception every time.
Final Answer:
The mimetype check always throws because of incorrect logical operator -> Option A
Quick Check:
Use AND (&&) to check mimetype correctly [OK]
Hint: Use && to check if mimetype is neither png nor jpeg [OK]
Common Mistakes:
Using || instead of && in mimetype checks
Forgetting to return the file after validation
Throwing wrong exception types
5. You want to create a file validation pipe that only accepts PDF files smaller than 2MB and throws a clear error if validation fails. Which of the following code snippets correctly implements this?
hard
A. export class PdfValidationPipe implements PipeTransform {
transform(file: Express.Multer.File) {
if (!file) throw new BadRequestException('File is required');
if (file.mimetype === 'application/pdf') throw new BadRequestException('Only PDFs allowed');
if (file.size > 2_000_000) throw new BadRequestException('File too large');
return file;
}
}
B. export class PdfValidationPipe implements PipeTransform {
transform(file: Express.Multer.File) {
if (!file) throw new BadRequestException('File is required');
if (file.mimetype !== 'application/pdf') throw new BadRequestException('Only PDFs allowed');
if (file.size >= 2_000_000) throw new BadRequestException('File too large');
return file;
}
}
C. export class PdfValidationPipe implements PipeTransform {
transform(file: Express.Multer.File) {
if (!file) throw new BadRequestException('File is required');
if (file.mimetype !== 'application/pdf' && file.size > 2_000_000) throw new BadRequestException('Invalid file');
return file;
}
}
D. export class PdfValidationPipe implements PipeTransform {
transform(file: Express.Multer.File) {
if (!file) throw new BadRequestException('File is required');
if (file.mimetype !== 'application/pdf' || file.size > 2_000_000) throw new BadRequestException('Invalid file');
return file;
}
}
Solution
Step 1: Verify correct logic for presence and mimetype
Check if (!file) throw, then if (file.mimetype !== 'application/pdf') throw 'Only PDFs allowed'. Uses !== to reject non-PDFs.
Step 2: Separate size check for smaller than 2MB
if (file.size >= 2_000_000) throw 'File too large'. Uses >= to reject 2MB or larger.
Step 3: Eliminate distractors
B throws if PDF; C's && accepts non-PDF if small; D's > accepts exactly 2MB.
Final Answer:
export class PdfValidationPipe implements PipeTransform {
transform(file: Express.Multer.File) {
if (!file) throw new BadRequestException('File is required');
if (file.mimetype !== 'application/pdf') throw new BadRequestException('Only PDFs allowed');
if (file.size >= 2_000_000) throw new BadRequestException('File too large');
return file;
}
} -> Option B
Quick Check:
!== mimetype, >= size, separate ifs [OK]
Hint: Check each condition separately with !== and clear exceptions [OK]
Common Mistakes:
Using === instead of !== for mimetype check
Combining conditions incorrectly with && or ||
Not throwing specific error messages
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.