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

NestJS多Swagger文档:如何让接口仅在指定文档显示

解决NestJS中接口在指定Swagger路由隐藏/显示的问题

你遇到的这个需求确实很常见——@ApiExcludeEndpoint是全局生效的,没法针对特定Swagger文档做区分,我这里有几个实用的方案可以解决这个问题:

方案一:自定义装饰器+文档转换过滤(最灵活)

这个方案适合需要在同一个控制器里区分不同Swagger文档显示的场景,实现起来也很直观:

  1. 创建自定义装饰器,给接口标记需要排除的Swagger文档名称:
import { applyDecorators } from '@nestjs/common';
import { ApiOperation } from '@nestjs/swagger';

// 自定义装饰器:标记接口在哪些Swagger文档中隐藏
export const ApiExcludeForSwagger = (...swaggerNames: string[]) => 
  applyDecorators(
    ApiOperation({
      // 用Swagger自定义扩展字段存储排除规则
      'x-exclude-for-swagger': swaggerNames,
    }),
  );
  1. 修改constructSwagger函数,在生成Swagger文档时过滤指定接口:
    利用SwaggerModule.createDocument的transform选项,我们可以在文档生成后,根据当前Swagger配置的名称,自动移除标记了要排除的接口:
const document = SwaggerModule.createDocument(app, documentConfig, {
  operationIdFactory: (controllerKey: string, methodKey: string) =>
    `[${controllerKey}] ${methodKey}`,
  include: modules,
  // 添加文档转换逻辑
  transform: (generatedDocument) => {
    const currentSwaggerName = config.name;
    // 遍历所有路径和方法,过滤需要隐藏的接口
    Object.keys(generatedDocument.paths).forEach(path => {
      Object.keys(generatedDocument.paths[path]).forEach(method => {
        const operation = generatedDocument.paths[path][method];
        const excludeForList = operation['x-exclude-for-swagger'];
        // 如果当前Swagger在排除列表中,删除该接口
        if (excludeForList?.includes(currentSwaggerName)) {
          delete generatedDocument.paths[path][method];
        }
      });
      // 如果某路径下没有剩余接口,直接删除整个路径
      if (Object.keys(generatedDocument.paths[path]).length === 0) {
        delete generatedDocument.paths[path];
      }
    });
    return generatedDocument;
  },
});
  1. 在目标接口上使用装饰器:
    比如你想让某个接口在API TEST(即test1SwaggerConfig的name)中隐藏,在/api/test2中正常显示:
@ApiExcludeForSwagger('API TEST')
@Get('/example')
async exampleEndpoint() {
  return '这个接口在/api/test1中隐藏,但在/api/test2中可见';
}

方案二:拆分控制器到不同模块(最简洁)

如果你的接口可以按Swagger文档的范围来拆分,那这个方案最省心:

  • 把需要在/api/test1中显示的接口放到Test1PublicController,归属Test1Module
  • 把需要仅在/api/test2中显示的接口放到Test2ExclusiveController,归属Test2Module
  • 然后在test1SwaggerConfig的modules数组里只包含Test1Module,test2SwaggerConfig里同时包含Test1Module和Test2Module

通过Swagger原生的include配置,自然就能实现不同文档显示不同接口的效果,完全不需要额外的过滤逻辑。

方案三:动态调整Swagger的include配置(折中方案)

如果不想拆分控制器,也可以在constructSwagger中根据当前Swagger配置,动态筛选要包含的控制器方法:
比如给控制器方法添加自定义元数据标记归属的Swagger文档,然后在生成文档时,通过反射获取元数据,只包含符合当前Swagger配置的方法。不过这个实现起来比方案一复杂,灵活性也稍差,一般更推荐方案一。


我自己在项目中用过方案一,适配性很强,完全能满足“同一接口在不同Swagger文档中显示/隐藏”的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:20:31