考虑控制器中的以下路由:
@Get('/:uuid')
findById(@Param() params: FindProjectParamsDto): Promise<Project> {
return this.projectsService.findById(params);
}
假设
FindProjectParamsDto
的定义如下:
export class FindProjectParamsDto extends PickType(ProjectDto, [
'id',
] as const) {}
(或未映射,但仅包含
id
属性)。我们还假设这个属性还有像 @IsNotEmpty()
或 @IsUUID()
这样的验证器。
您可以在这里轻松发现一个问题:在请求时,提取的路由参数是
uuid
,而params
应该有id
,因此id
为空。这样的请求总是会失败,因为验证器会导致如下响应:
{
"statusCode": 400,
"message": [
"id must be a UUID",
"id should not be empty"
],
"error": "Bad Request"
}
我想知道是否可以通过静态代码分析器自动防止这样的问题。显然,TypeScript 本身并没有发现这一点,因为它不关心路由字符串内容。但也许 Nest.js 已经有一个标准的解决方案了?
可能是一个标准的自动测试,它采用 DTO,使用验证器和/或示例(来自
@ApiProperty
)填充路由中的值,将其传递给控制器并检查它是否不会使其无效? (因为用有效值替换 "/:uuid"
后 ":id"
仍将是 "/:uuid"
,因此测试将失败)但是,这样的测试将给出假阴性结果: "/:isGoodEnough"
与 DTO 中的 isGood
可能会给出类似于 { isGood: "trueEnough" }
,但这显然比没有验证要好(最终,如果 isGood
有 @IsBooleanString()
,{ isGood: "trueEnough" }
不会通过)。
注意:如果自动测试方法可以同时应用于所有路由,那么它就足够了;为每条路线编写特定的自动测试的开销太大了。
@Get('/:uuid')
findById(@Param() param: string): Promise<Project> {
return this.projectsService.findById(param.uuid);
}
你可以这样做,无需 dto。