alw*_*loo 5 javascript node.js typescript class-validator nestjs
假设我有以下路线:
companies/{companyId}/departments/{departmentId}/employees
Run Code Online (Sandbox Code Playgroud)
是否可以分别验证两个资源 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,
) {}
Run Code Online (Sandbox Code Playgroud)
当单个路由中有多个参数时,我遇到了多种情况。我不想为每条路线创建单独的验证类。有没有办法以不同的方式处理这个问题?
aso*_*gor 11
截至 2022 年,NestJS 文档表示可以使用内置验证管道来验证路由参数。
在控制器中:
@Get(':id')
findOne(@Param() params: FindOneParams) {
return 'This action returns a user';
}
Run Code Online (Sandbox Code Playgroud)
验证类:
import { IsNumberString } from 'class-validator';
export class FindOneParams {
@IsNumberString()
id: number;
}
Run Code Online (Sandbox Code Playgroud)
参考:https: //docs.nestjs.com/techniques/validation#auto-validation
问题是你这里有一个普通的字符串。为了使验证起作用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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后您可以在控制器上使用它:
@UsePipes(ParamValidationPipe)
@Get(':companyId/departments/:departmentId/employees')
getEmployees(
@Param('companyId') companyId: ResourceId,
@Param('departmentId') departmentId: ResourceId,
) {
return `id1: ${companyId.id}, id2: ${departmentId.id}`;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6343 次 |
| 最近记录: |