3

假设我有以下路线:

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

是否可以分别验证两个资源 id ( companyId, departmentId)?我试过跟随但它不起作用。

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

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

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

4

2 回答 2

3

问题是你在这里有一个纯字符串。为了使验证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}`;
}
于 2019-03-27T22:30:08.457 回答
2

截至 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

于 2022-02-15T11:41:10.987 回答