假设我有以下路线:
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,
) {}
在多种情况下,单个路径中有多个参数。我不想为每条路线创建单独的验证类。有没有其他方法可以解决这个问题?
答案 0 :(得分:1)
问题是您在此处输入了纯字符串。为了使用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}`;
}