我想在我的CRUD API上应用服务器端验证。有问题的实体称为Employee
。我正在使用employee.dto
(如下所示)创建和更新端点。
class-validator包在create
方法上可以很好地工作,但是当我在update方法中将Partial<EmployeeDTO>
与DTO一起使用时,它将忽略DTO中的所有规则。
请使用下面的代码作为参考。
"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);
}
}
我可以解决的问题是为create
和update
方法创建单独的DTO,但是我不喜欢重复代码的想法。
答案 0 :(得分:4)
为了实现部分验证,您可以使用 PartialType
效用函数。你可以在这里读到它:
https://docs.nestjs.com/openapi/mapped-types#partial
您需要创建另一个类:
export class UpdateEmployeeDTO extends PartialType(EmployeeDTO) {}
然后在您的控制器中,您需要将 @Body data Partial<EmployeeDTO>
的类型替换为 UpdateEmployeeDto
。它应该是这样的:
@Patch(':id')
@UsePipes(ValidationPipe)
updateEmployee(@Param('id') id: number, @Body() data: UpdateEmployeeDTO) {
return this.employeeService.update(id, data);
}
请记住,您应该像文档中建议的那样从 PartialType
导入 @nestjs/mapped-types
,而不是从 @nestjs/swagger
导入。可以在 here
答案 1 :(得分:1)
对于这个答案,我会做一个猜测,并假设您使用NestJS' documentation中提供的ValidationPipe
或近似导数。
您的updateEmployee
方法的参数data
类型为Partial
,它不会发出任何类型的元数据。使ValidationPipe
使用class-transformer
模块实例化,导致class-validator
模块验证一个普通对象,而不是EmployeeDTO
。
为使验证生效,data
参数的类型应为类。
您可以创建单独的DTO来创建和更新您的实体,或者如果要保留单个类,则可以使用validation groups。