NestJS自定义参数装饰器如何自动生成Swagger查询参数文档
NestJS 自定义查询参数装饰器无法生成Swagger文档的解决方案
核心原因
NestJS Swagger 模块扫描控制器路由时,通过反射读取ROUTE_ARGS_METADATA元数据识别参数位置,只有标记为Query类型的参数才会被解析为查询参数,同时读取参数的TS类型关联对应DTO生成文档。
你自定义的@Aqp()装饰器仅实现了参数解析逻辑,没有写入对应元数据标记,Swagger会忽略该参数,自然不会生成对应的文档结构。
推荐实现方案
以下方案不需要修改现有控制器的写法,替换后既保留你自定义的参数处理逻辑,又能和原生@Query()一样自动触发DTO校验、自动生成Swagger文档,无版本兼容问题。
import { createParamDecorator, ExecutionContext, ROUTE_ARGS_METADATA, RouteParamtypes } from '@nestjs/common'; /** * 自定义查询参数解析装饰器,替代原生@Query(),支持自动校验、自动生成Swagger文档 */ export const Aqp = createParamDecorator( (_data: unknown, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); const rawQuery = request.query; // 在这里写入你原本的差异化处理逻辑,比如参数格式转换、过滤规则解析、字段映射等 // 示例:return aqp.parse(rawQuery); return rawQuery; }, // 参数绑定阶段写入和原生@Query()完全一致的元数据 (target, propertyKey, parameterIndex) => { // 读取当前路由方法已有的参数元数据 const existingRouteArgs = Reflect.getMetadata( ROUTE_ARGS_METADATA, target.constructor, propertyKey ) || {}; // 给当前参数打上Query类型标记,格式和Nest内部原生装饰器写入的完全一致 existingRouteArgs[`${RouteParamtypes.QUERY}:${parameterIndex}`] = { index: parameterIndex, data: undefined, pipes: [], }; // 回写元数据 Reflect.defineMetadata( ROUTE_ARGS_METADATA, existingRouteArgs, target.constructor, propertyKey ); } );
注意事项
- 你的
AqpDto需要保持和之前一致的写法,字段上保留class-validator校验装饰器、@ApiProperty()等Swagger装饰器,不需要额外修改 - 全局挂载的
ValidationPipe会自动对该装饰器解析后的参数做DTO校验,和原生@Query()行为完全一致 - Swagger生成的参数结构、swagger-client识别的参数定义和原生
@Query()效果完全相同,不会出现参数丢失、传参错误的问题 - 该实现兼容NestJS 7.x到10.x所有主流版本,不需要依赖Swagger模块的内部私有API,升级版本不会失效
内容的提问来源于stack exchange,提问作者Raphael Arias
相关产品推荐
相关产品推荐

