验证不适用于 Partial<DTO> - NestJS
Validation does not work with Partial<DTO> - NestJS
我想在我的 CRUD API 上应用服务器端验证。有问题的实体称为 Employee
。我正在使用 employee.dto
(如下所示)来创建和更新端点。
class-validator 包在 create
方法上运行良好,但当我在更新方法中将它与 Partial<EmployeeDTO>
一起使用时,它会忽略 DTO 中的所有规则。
请参考以下代码。
套餐
"class-transformer": "^0.2.3",
"class-validator": "^0.10.0",
员工 DTO
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,但我不喜欢重复代码的想法。
对于这个答案,我将进行猜测并假设您使用 NestJS' documentation 中提供的 ValidationPipe
或其近似导数。
您的 updateEmployee
方法的参数 data
类型是 Partial
,它不发出任何类型元数据。 ValidationPipe
使用 class-transformer
模块实例化它,导致 class-validator
模块验证普通对象,而不是 EmployeeDTO
.
要使验证生效,data
参数的类型应为 class。
您可以制作单独的 DTO 来创建和更新您的实体,或者如果您想保留一个 class.
,则使用 validation groups
为了实现部分验证,可以使用PartialType
效用函数。你可以在这里读到它:
https://docs.nestjs.com/openapi/mapped-types#partial
您需要创建另一个 class:
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);
}
请记住,您应该从 @nestjs/mapped-types
导入 PartialType
,而不是像文档中建议的那样从 @nestjs/swagger
导入。有关更多信息,请参见 here
我想在我的 CRUD API 上应用服务器端验证。有问题的实体称为 Employee
。我正在使用 employee.dto
(如下所示)来创建和更新端点。
class-validator 包在 create
方法上运行良好,但当我在更新方法中将它与 Partial<EmployeeDTO>
一起使用时,它会忽略 DTO 中的所有规则。
请参考以下代码。
套餐
"class-transformer": "^0.2.3",
"class-validator": "^0.10.0",
员工 DTO
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,但我不喜欢重复代码的想法。
对于这个答案,我将进行猜测并假设您使用 NestJS' documentation 中提供的 ValidationPipe
或其近似导数。
您的 updateEmployee
方法的参数 data
类型是 Partial
,它不发出任何类型元数据。 ValidationPipe
使用 class-transformer
模块实例化它,导致 class-validator
模块验证普通对象,而不是 EmployeeDTO
.
要使验证生效,data
参数的类型应为 class。
您可以制作单独的 DTO 来创建和更新您的实体,或者如果您想保留一个 class.
为了实现部分验证,可以使用PartialType
效用函数。你可以在这里读到它:
https://docs.nestjs.com/openapi/mapped-types#partial
您需要创建另一个 class:
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);
}
请记住,您应该从 @nestjs/mapped-types
导入 PartialType
,而不是像文档中建议的那样从 @nestjs/swagger
导入。有关更多信息,请参见 here