Javascript 验证不适用于部分<;DTO>;-内斯特

Javascript 验证不适用于部分<;DTO>;-内斯特,javascript,api,nestjs,server-side-validation,class-validator,Javascript,Api,Nestjs,Server Side Validation,Class Validator,我想在我的CRUDAPI上应用服务器端验证。所涉及的实体称为Employee。我正在使用employee.dto(如下所示)来创建和更新端点 class validator包在create方法上运行良好,但在update方法中将其与Partial一起使用时,会忽略DTO中的所有规则 请使用下面的代码作为参考 包装 员工DTO 员工控制员 导入{ 控制器, Param, 邮递 身体, 放, 使用管道, }来自“@nestjs/common”; 从“./dto/employee.dto”导入{Emp

我想在我的CRUDAPI上应用服务器端验证。所涉及的实体称为
Employee
。我正在使用
employee.dto
(如下所示)来创建和更新端点

class validator包在
create
方法上运行良好,但在update方法中将其与
Partial
一起使用时,会忽略DTO中的所有规则

请使用下面的代码作为参考

包装 员工DTO 员工控制员
导入{
控制器,
Param,
邮递
身体,
放,
使用管道,
}来自“@nestjs/common”;
从“./dto/employee.dto”导入{EmployeeDTO};
从“/employee.service”导入{EmployeeService};
从“../shared/pipes/validation.pipe”导入{ValidationPipe};
@财务总监(“员工”)
导出类EmployeeController{
构造函数(私有employeeService:employeeService){}
@Post()
@使用管道(验证管道)
addNewEmployee(@Body()数据:EmployeeDTO){
返回此.employeeService.create(数据);
}
@Put(':id')
@使用管道(验证管道)
updateEmployee(@Param('id')id:number,@Body()数据:Partial){
返回此.employeeService.update(id,数据);
}
}
可能的解决办法
我能想到的解决方法是为
create
update
方法创建单独的DTO,但我不喜欢重复代码的想法。

对于这个答案,我会猜测一下,并假设您使用中提供的
验证管道,或者是一个近似的衍生工具

您的
updateEmployee
方法的参数
data
类型是
Partial
,它不发出任何类型元数据。让
验证管道
使用
类转换器
模块对其进行实例化,从而使
类验证程序
模块验证普通对象,而不是
员工待办事项

要使验证生效,
data
参数的类型应为类。
您可以创建单独的DTO来创建和更新实体,如果您想保留单个类,也可以使用。

为了实现部分验证,您可以使用
PartialType
实用程序功能。您可以在此处阅读:

您需要创建另一个类:

export class UpdateEmployeeDTO extends PartialType(EmployeeDTO) {}
然后在控制器中,需要将
@Body data Partial
的类型替换为
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
导入。更多信息请访问

谢谢您的回答!我也计划在将来整合Swagger。有单独的DTO还是保留一个类更好?是的,我正在使用
验证管道
来招摇,我认为有单独的DTO会使文档更清晰。是的,我有同样的想法,尽管它重复了很多代码。谢谢。虽然它复制了一些代码,但在我看来,它允许您更好地理解和分离关注点。另外,我假设在创建员工时,DTO类的某些属性是必需的,而在更新时,这些属性是可选的。请您在回答中添加以下内容:
PartialType
需要从
@nestjs/mapped types
导入?这些文件具有误导性。另外,
updateEmployee
函数也应该是PATCH not PUT。PUT用于替换所有内容,修补程序仅更新特定值。@Mick感谢您的建议。我离开了
Put
,因为它最初用于问题中,但你是对的-我们应该使用
Patch
,因为
PartialType
只允许编辑请求对象的一部分,而不必编辑整个对象。我已经改变了,谢谢。我想知道
@nestjs/mapped types
是否是正确的导入。为什么你认为文件有误导性?我编写了一些示例单元测试,并验证了
@nestjs/swagger
包(文档中建议)中的
PartialType
也能正常工作。只有在实际使用swagger时,它才不能与
@nestjs/swagger
一起工作。否则它应该是
@nestjs/mapped types
。它没有被记录,但有一个公开的问题需要记录:谢谢@Mick,我不知道。我已经在我的帖子中介绍了这方面的信息。现在这里有文档记录:->甚至还有第三个库
@nestjs/graphql
,在使用graphql时需要使用它。
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);
  }
}
export class UpdateEmployeeDTO extends PartialType(EmployeeDTO) {}
@Patch(':id')
@UsePipes(ValidationPipe)
updateEmployee(@Param('id') id: number, @Body() data: UpdateEmployeeDTO) {
    return this.employeeService.update(id, data);
}