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

如何将NestJS的reflect metadata注入到Swagger对应字段中

NestJS自定义元数据同步到Swagger实现方案

你可以通过以下两种方案实现将@Rights、@Level等自定义装饰器挂载的元数据展示到Swagger接口文档中,不需要修改现有控制器的业务代码。


方案1:改造自定义装饰器(最简实现,推荐小项目使用)

利用NestJS的applyDecorators工具,将元数据设置逻辑和Swagger注解逻辑组合到同一个自定义装饰器中:

步骤1:改造自定义装饰器

import { SetMetadata, applyDecorators } from '@nestjs/common';
import { ApiExtension } from '@nestjs/swagger';

// 原@Rights装饰器改造
export const Rights = (rights: string) => {
  return applyDecorators(
    SetMetadata('rights', rights), // 原有设置元数据的逻辑保留
    ApiExtension('x-required-rights', rights) // 新增Swagger扩展字段
  );
};

// 原@Level装饰器改造
export const Level = (level: 'read' | 'write') => {
  return applyDecorators(
    SetMetadata('level', level), // 原有设置元数据的逻辑保留
    ApiExtension('x-required-permission-level', level) // 新增Swagger扩展字段
  );
};

步骤2:开启Swagger扩展字段展示

在项目入口文件main.ts的Swagger初始化配置中,开启扩展字段展示:

SwaggerModule.setup('api-doc', app, document, {
  swaggerOptions: {
    showExtensions: true // 展示所有自定义扩展字段
  }
});

配置完成后,所有挂载了@Rights、@Level装饰器的接口,都会在Swagger的接口详情区域自动展示对应的权限要求字段。


方案2:全局自动注入元数据(无侵入,推荐中大型项目使用)

如果你不想修改现有自定义装饰器的代码,可以在Swagger文档生成阶段,通过Reflector全局扫描所有路由的元数据,自动注入到Swagger配置中:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { Reflector } from '@nestjs/core';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const reflector = app.get(Reflector);

  // 基础Swagger配置
  const swaggerConfig = new DocumentBuilder()
    .setTitle('业务接口文档')
    .setVersion('1.0')
    .build();
  const swaggerDocument = SwaggerModule.createDocument(app, swaggerConfig);

  // 遍历所有路由,注入自定义元数据到Swagger
  const serverRoutes = app.getHttpServer()._events.request._router.stack;
  serverRoutes.forEach(route => {
    if (!route?.route) return;
    const { path, stack, methods } = route.route;
    const handler = stack[0].handle;
    const requestMethod = Object.keys(methods)[0];

    // 读取自定义元数据
    const requiredRights = reflector.get('rights', handler);
    const requiredLevel = reflector.get('level', handler);
    if (!requiredRights && !requiredLevel) return;

    // 匹配Swagger文档中的对应接口
    const pathItem = swaggerDocument.paths[path];
    if (!pathItem || !pathItem[requestMethod]) return;

    // 注入元数据到Swagger接口配置
    const operation = pathItem[requestMethod];
    if (requiredRights) operation['x-required-rights'] = requiredRights;
    if (requiredLevel) operation['x-required-permission-level'] = requiredLevel;
  });

  // 挂载Swagger文档
  SwaggerModule.setup('api-doc', app, swaggerDocument, {
    swaggerOptions: {
      showExtensions: true
    }
  });

  await app.listen(3000);
}
bootstrap();

该方案完全不需要修改现有业务代码和自定义装饰器代码,全局统一处理所有接口的元数据同步逻辑。


内容的提问来源于stack exchange,提问作者Vlad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 15:36:01