我可以通过静态分析器(编译时)或非特定的自动测试来防止 Nest.js 路由模式及其参数 DTO 不匹配吗?

Can I prevent mismatch of a Nest.js route pattern and its param DTO via a static analyser (compile-time) or a non-specific autotest?

提问人:YakovL 提问时间:11/9/2023 最后编辑:YakovL 更新时间:11/10/2023 访问量:31

问:

请考虑控制器中的以下路由:

@Get('/:uuid')
findById(@Param() params: FindProjectParamsDto): Promise<Project> {
    return this.projectsService.findById(params);
}

假设它是这样定义的:FindProjectParamsDto

export class FindProjectParamsDto extends PickType(ProjectDto, [
  'id',
] as const) {}

(或未映射,但仅包含属性)。我们还要说这个属性也有验证器,比如 or 。id@IsNotEmpty()@IsUUID()

在这里,你可以很容易地发现一个问题:在请求中,提取的路由参数是 ,而应该有 ,因此是空的。这样的请求总是失败的,因为验证器会导致这样的响应:uuidparamsidid

{
  "statusCode": 400,
  "message": [
    "id must be a UUID",
    "id should not be empty"
  ],
  "error": "Bad Request"
}

我想知道是否可以通过静态代码分析器自动防止此类问题。显然,TypeScript 本身并没有发现这一点,因为它不关心路由字符串内容。但是,对于Nest .js,可能已经有一个标准的解决方案了吗?

可能是一个标准的自动测试,它接受 DTO,使用验证器和/或示例(来自)填充路由中的值,将其传递给控制器并检查它是否使其无效?(因为代入有效值后仍将是,因此测试将失败)不过,这样的测试会给出假阴性结果:在 DTO 中可能会给出类似 的东西,但这显然比没有验证要好(最后,如果有,则不会通过)。@ApiProperty"/:uuid"":id""/:uuid""/:isGoodEnough"isGood{ isGood: "trueEnough" }isGood@IsBooleanString(){ isGood: "trueEnough" }

注意:如果自动测试方法可以同时应用于所有路由,那就足够了;为每个路由编写特定的自动测试开销太大了。

PS:这个项目使用自定义eslint规则做类似的事情,但仅适用于非DTO参数。这可能是一种可用于处理此问题的方法。

TypeScript 验证 nestjs 静态分析

评论

0赞 Aluan Haddad 11/9/2023
您可以重载装饰器工厂的签名(使用模块扩充),这样,如果它传递了字符串,它将返回一个装饰器,如果应用于非所需类型的方法,它将发出编译错误。Get"/:uuid"params
0赞 YakovL 11/9/2023
@AluanHaddad听起来很有趣。关于如何实现这一点的任何指示?
0赞 Aluan Haddad 11/9/2023
我没有使用过 Nest.js。它是使用旧版装饰器还是使用新的实现标准?

答:

-1赞 Nyilynn Htwe 11/9/2023 #1
@Get('/:uuid')
findById(@Param() param: string): Promise<Project> {
return this.projectsService.findById(param.uuid);
}

你可以在没有 dto 的情况下这样做。

评论

0赞 YakovL 11/9/2023
这不是我要问的。DTO 用于为前端等提供验证。为了简单起见,我还提供了一个带有单个参数的示例;情况并非总是如此。