【问题标题】:Is it possible to validate single route parameter?是否可以验证单个路由参数?
【发布时间】:2019-08-18 11:35:17
【问题描述】:

假设我有以下路线:

companies/{companyId}/departments/{departmentId}/employees

是否可以分别验证两个资源 ID(companyIddepartmentId)?我已经尝试过,但它不起作用。

class ResourceId {
  @IsNumberString()
  @StringNumberRange(...) // my custom validator
  id: number;
}

@Get(':companyId/departments/:departmentId/employees')
getEmployees(
  @Param('companyId') companyId: ResourceId,
  @Param('departmentId') departmentId: ResourceId,
) {}

当单个路由中有多个参数时,我有多种情况。我不想为每条路线创建单独的验证类。有没有办法以不同的方式处理这个问题?

【问题讨论】:

    标签: javascript node.js typescript nestjs class-validator


    【解决方案1】:

    截至 2022 年,NestJS 文档表示可以使用内置验证管道来验证路由参数。

    在控制器中:

    @Get(':id')
    findOne(@Param() params: FindOneParams) {
      return 'This action returns a user';
    }
    

    验证类:

    import { IsNumberString } from 'class-validator';
    
    export class FindOneParams {
      @IsNumberString()
      id: number;
    }
    

    参考:https://docs.nestjs.com/techniques/validation#auto-validation

    【讨论】:

      【解决方案2】:

      问题是你这里有一个纯字符串。要使用class-validator 进行验证,您必须实例化一个类,在您的情况下为ResourceId。内置的 ValidationPipe 期望值是 {id: '123'} 而不是 '123' 能够自动转换它。但是您可以轻松地创建自己的验证管道,从而完成这种额外的转换。

      export class ParamValidationPipe implements PipeTransform {
        async transform(value, metadata: ArgumentMetadata) {
          if (metadata.type === 'param') {
            // This is the relevant part: value -> { id: value }
            const valueInstance = plainToClass(metadata.metatype, { id: value });
            const validationErrors = await validate(valueInstance);
            if (validationErrors.length > 0) {
              throw new BadRequestException(validationErrors, 'Invalid route param');
            }
            return valueInstance;
          } else {
            return value;
          }
        }
      }
      

      然后您可以在控制器上使用它:

      @UsePipes(ParamValidationPipe)
      @Get(':companyId/departments/:departmentId/employees')
      getEmployees(
        @Param('companyId') companyId: ResourceId,
        @Param('departmentId') departmentId: ResourceId,
      ) {
        return `id1: ${companyId.id}, id2: ${departmentId.id}`;
      }
      

      【讨论】:

      • 您也可以使用class-transformer-validator 一次性完成所有转换、验证和检查错误列表步骤:)
      • 好点。 :-) 我不会改变我的答案,因为添加有关安装另一个软件包的注释会使它更长,但我认为这是一个非常有用的评论。
      猜你喜欢
      • 2019-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-11
      • 1970-01-01
      • 2021-05-11
      • 1970-01-01
      相关资源
      最近更新 更多