You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:15:38