Learn how to implement NestJS 10 request validation and automatic DTO transformation using class-validator and class-transformer. This combination ensures incoming payloads meet your API contracts while converting plain JSON into strongly typed DTO instances. By following the steps below, you’ll reduce boilerplate, improve maintainability, and catch errors early.
Why Request Validation Matters in NestJS
Without validation, malicious or malformed data can slip into your services, leading to bugs, security vulnerabilities, or inconsistent state. NestJS provides a built‑in ValidationPipe that works seamlessly with class-validator to enforce declarative rules on DTO classes. Automatic transformation via class-transformer then maps raw payloads to typed objects, eliminating manual mapping code.
Setting Up class-validator and class-transformer in NestJS 10
Installing the Packages
Run the following command in your project root to add the required dependencies:
npm i class-validator class-transformer
Both libraries are peer‑dependencies of @nestjs/core, so no additional configuration is needed beyond enabling the validation pipe.
Enabling the Global Validation Pipe
In main.ts, instantiate the ValidationPipe with options that whitelist and forbid non‑whitelisted values:
import { ValidationPipe } from '@nestjs/pipes';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(
new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true })
);
await app.listen(3000);
}
bootstrap();
The transform: true flag tells NestJS to use class-transformer for automatic payload conversion before validation runs.
Creating Validation DTOs with class-validator
Basic Decorators
Define a DTO class and attach decorators from class-validator to each property. Common decorators include @IsString(), @IsInt(), @IsEmail(), @IsOptional(), and @Length().
Nested Objects and Arrays
For nested objects, use @ValidateNested() alongside @Type(() => ChildDto) to ensure the inner class is also validated. Arrays of DTOs are validated with @ArrayMinSize() and @ArrayMaxSize() or @ValidateNested({ each: true }).
Automatic DTO Transformation with class-transformer
Using @Type() for Explicit Conversion
The @Type() decorator indicates the target type for a property during transformation. For example, @Type(() => Date) converts an ISO string to a JavaScript Date instance.
plainToInstance for Manual Transformation
When you need more control, call plainToInstance(UserDto, payload) inside a service or guard. This method respects @Expose() and @Exclude() decorators, letting you shape the output exactly as required.
Combining Validation and Transformation in Controllers
Example: POST /users Endpoint
Below is a complete controller method that receives a CreateUserDto, validates it, and returns the transformed DTO:
@Post()
async createUser(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
Because the global ValidationPipe has transform: true, NestJS automatically:
- Converts the raw JSON body to an instance of CreateUserDto using class-transformer.
- Runs all validation decorators defined on the DTO.
- Throws a BadRequestException with a detailed error array if any rule fails.
Advanced Techniques: Custom Validation Decorators and Async Validators
If built‑in decorators don’t cover your business rules, you can create a custom validator by implementing the ValidatorConstraint interface and registering it with @RegisterValidatorConstraint. Async validators are useful for database checks, such as ensuring a username is unique.
Handling Validation Errors Globally
NestJS already formats validation errors into a consistent JSON response. You can further customize the format by creating a custom ExceptionFilter that catches BadRequestException and reshapes the error payload to match your API guidelines.
Performance Considerations and Best Practices
Validation adds a small overhead, but the benefits far outweigh the cost. Keep DTOs lean, avoid overly complex custom validators, and enable whitelist to strip unexpected properties early. For high‑throughput endpoints, consider using the transform option selectively or applying validation only where needed via method‑level pipes.
Conclusion
Implementing request schema validation and automatic DTO transformation in NestJS 10 with class-validator and class-transformer creates a robust, type‑safe API layer that reduces bugs and improves developer productivity. Start by installing the packages, enabling the global ValidationPipe, and crafting DTOs rich with decorators—then let NestJS handle the rest.