6

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

class-validator 包在该create方法上运行良好,但当我Partial<EmployeeDTO>在 update 方法中使用它时会忽略 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,但我不喜欢重复代码的想法。

4

2 回答 2

9

为了实现部分验证,可以使用PartialType实用程序函数。你可以在这里阅读: https ://docs.nestjs.com/openapi/mapped-types#partial

您需要创建另一个类:

export class UpdateEmployeeDTO extends PartialType(EmployeeDTO) {}

然后在您的控制器中,您需要替换 to 的@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

于 2021-01-16T10:25:18.027 回答
6

对于这个答案,我会猜测一下,并假设您使用NestJS 文档ValidationPipe中提供的内容,或类似的派生词。

您的updateEmployee方法的参数data类型是Partial,它不会发出任何类型元数据。使用模块ValidationPipe实例化它class-transformer,导致class-validator模块验证普通对象,而不是EmployeeDTO.

为了使验证工作,data参数的类型应该是一个类。您可以创建单独的 DTO 来创建和更新您的实体,或者如果您想保留一个类,则可以使用验证组。

于 2019-09-05T07:42:31.447 回答