I want to apply server-side validation on my CRUD API. The entity in question is called Employee
. I am using an employee.dto
(shown below) for the create and update endpoints.
The class-validator package works fine on the create
method but ignores all rules in the DTO when I use it with Partial<EmployeeDTO>
in the update method.
Please use the code below for reference.
"class-transformer": "^0.2.3",
"class-validator": "^0.10.0",
import { IsString, IsNotEmpty, IsEmail, IsEnum } from 'class-validator';
import { EmployeeRoles } from '../../entities/employee.entity';
export class EmployeeDTO {
@IsString()
@IsEmail()
@IsNotEmpty()
email: string;
@IsString()
@IsNotEmpty()
password: string;
@IsString()
@IsNotEmpty()
username: string;
@IsString()
@IsNotEmpty()
fullName: string;
@IsString()
@IsNotEmpty()
@IsEnum(EmployeeRoles)
role: string;
}
import {
Controller,
Param,
Post,
Body,
Put,
UsePipes,
} from '@nestjs/common';
import { EmployeeDTO } from './dto/employee.dto';
import { EmployeeService } from './employee.service';
import { ValidationPipe } from '../shared/pipes/validation.pipe';
@Controller('employee')
export class EmployeeController {
constructor(private employeeService: EmployeeService) {}
@Post()
@UsePipes(ValidationPipe)
addNewEmployee(@Body() data: EmployeeDTO) {
return this.employeeService.create(data);
}
@Put(':id')
@UsePipes(ValidationPipe)
updateEmployee(@Param('id') id: number, @Body() data: Partial<EmployeeDTO>) {
return this.employeeService.update(id, data);
}
}
I work around I can think of is creating separate DTOs for create
and update
methods, but I don't like the idea of repeating the code.
For this answer, I'll take a guess and assume that you use the ValidationPipe
provided in the NestJS' documentation, or a close derivative.
Your updateEmployee
method's argument data
type is Partial
, which doesn't emit any type metadata. for the ValidationPipe
to instantiate it using the class-transformer
module, resulting in the class-validator
module to validate a plain object, and not an EmployeeDTO
.
For the validation to work, the type of the data
argument should be a class.
You could either make separate DTOs to create and update your entity, or use validation groups if you want to keep a single class.