验证不适用于Partial <DTO>-NestJS

时间:2019-09-05 01:34:57

标签: javascript api nestjs server-side-validation class-validator

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

class-validator包在create方法上可以很好地工作,但是当我在update方法中将Partial<EmployeeDTO>与DTO一起使用时,它将忽略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);
  }
}

可能的解决方案

我可以解决的问题是为createupdate方法创建单独的DTO,但是我不喜欢重复代码的想法。

2 个答案:

答案 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