为 ApiParam 和 ApiQuery 定义 DTO

Posted

技术标签:

【中文标题】为 ApiParam 和 ApiQuery 定义 DTO【英文标题】:define DTO for ApiParam and ApiQuery 【发布时间】:2020-08-09 22:34:38 【问题描述】:

我正在使用nestjs swagger module 并想创建我的 API 文档。对于依赖于请求正文的端点,我可以将 DTO 类分配给文档,例如

@ApiBody( type: CreateUserDTO )

一些端点也依赖于请求参数或查询。对于参数,我会做类似的事情

@ApiParam( type: GetUserByIdDTO )

(我知道这是一个不好的例子,因为用户 ID 不需要 DTO,但我们假设您想使用类验证器使用 DTO 类验证您的参数)

但我收到此错误

类型参数 ' type: typeof GetUserByIdDTO; ' 不可赋值 到“ApiParamOptions”类型的参数。缺少属性“名称” 在类型'类型:typeof GetUserByIdDTO; ' 但在类型中是必需的 'ApiParamMetadata'。

对于查询,我会做类似的事情

@ApiQuery( type: GetUsersDTO )

得到这个错误

类型参数 ' type: typeof GetUsersDTO; ' 不可分配给 'ApiQueryOptions' 类型的参数。缺少属性“名称” type ' type: typeof GetUsersDTO; ' 但在类型中是必需的 'ApiQueryMetadata'。

所以APIBody 装饰器似乎工作正常,但我该如何修复我的APIParamAPIQuery 装饰器?

【问题讨论】:

【参考方案1】:

@ApiQuery@ApiParam 在使用命名参数/查询时是必需的,例如 @Query('pageSize') o @Param('id')。在这种情况下,NestJS Swagger 模块应该直接从指定的 DTO 对象中提取信息,例如:

async findElements(@Query() query: ElementsQueryDto) 
  // ...

需要注意的重要一点是,Dtos 应该是类,而不是接口。

【讨论】:

我用 ApiProperty 装饰器记录了我的 dto 字段。是的,这似乎已经足够了。所以你说不需要ApiQueryApiParam 装饰器,因为这段代码很好public getUsers(@Query() getUsersDTO: GetUsersDTO): Promise<User[]> /* ... */ ,因为swagger 模块将自己记录来自dto 的字段? 没错,这是 swagger nestjs 模块的默认行为,ApiQuery 或 ApiParam 旨在作为不需要 Dto 的更简单场景的后备/简写。

以上是关于为 ApiParam 和 ApiQuery 定义 DTO的主要内容,如果未能解决你的问题,请参考以下文章

@Requestbody@ApiParam @PathVariable @RequestParam三者区别

@ApiParam @RequestParam @PathVariable 用法

Swagger常见注解@API、@ApiOperation、@ApiParam等

Swagger Codegen Maven插件,带有路径变量和请求参数,OpenApi产生不起作用的代码

@ApiOperation注解,@FeignClient

语句 lambda 可以替换为表达式 lambda