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

NestJS中@nestjs/swagger配置API文档的最佳实践

@nestjs/swagger 静态配置文件说明

@nestjs/swagger 没有默认的静态配置文件扫描路径,你把写好的 swagger.json 或者 swagger.yaml 随便放项目哪个目录,框架都不会主动读取生效。它的默认逻辑是启动时动态扫描控制器、路由、装饰器元数据自动生成文档结构。

如果你确实要使用本地维护的静态swagger文件,可以手动写读取逻辑加载,比如把静态文件放在 src/config/swagger/ 目录下,初始化Swagger时跳过自动生成步骤,直接读取文件内容传入即可:

// main.ts Swagger初始化片段
import * as fs from 'fs';
import * as path from 'path';
import { SwaggerModule } from '@nestjs/swagger';

// 读取本地静态swagger文件
const staticSwaggerDoc = JSON.parse(
  fs.readFileSync(path.join(process.cwd(), 'src/config/swagger/swagger.json'), 'utf-8')
);
SwaggerModule.setup('api/docs', app, staticSwaggerDoc);

不推荐这种方式:静态文件和实际接口代码完全解耦,后续改接口逻辑、改参数时很容易忘记同步文档,时间长了文档和实际接口完全对不上,维护成本极高。

减少重复配置的最佳实践

不用逐接口堆装饰器写配置,用下面几种方式可以覆盖90%的文档场景,重复代码量能降到最低:

  • 全局统一配置通用规则
    通用的鉴权方式、接口公共说明、全局通用错误码,全部在Swagger初始化阶段统一配置,不用每个接口单独写。比如批量给所有接口追加401、403、500这类通用错误响应:
    import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
    
    const swaggerConfig = new DocumentBuilder()
      .setTitle('业务系统API文档')
      .setVersion('1.0')
      .addBearerAuth() // 全局统一添加JWT鉴权请求头
      .build();
    
    const document = SwaggerModule.createDocument(app, swaggerConfig);
    // 遍历所有接口批量追加通用响应
    Object.values(document.paths).forEach(pathItem => {
      Object.values(pathItem).forEach(operation => {
        if (typeof operation !== 'object' || !operation.responses) return;
        operation.responses['401'] = { description: '登录状态已失效,请重新登录' };
        operation.responses['403'] = { description: '当前账号无该接口访问权限' };
        operation.responses['500'] = { description: '服务内部异常' };
      });
    });
    SwaggerModule.setup('api/docs', app, document);
    
  • 封装自定义装饰器复用重复逻辑
    对于某一类通用的接口配置(比如分页查询参数、增删改查的通用响应、固定的接口描述结构),用applyDecorators把多个Swagger装饰器打包成一个自定义装饰器,用的时候直接加在接口上就行,不用重复写一堆装饰器:
    import { applyDecorators } from '@nestjs/common';
    import { ApiOperation, ApiQuery, ApiResponse } from '@nestjs/swagger';
    
    // 封装分页接口通用配置装饰器
    export function ApiPagination(summary: string) {
      return applyDecorators(
        ApiOperation({ summary }),
        ApiQuery({ name: 'page', type: Number, required: false, description: '页码,默认值1' }),
        ApiQuery({ name: 'pageSize', type: Number, required: false, description: '每页条数,默认值10' }),
        ApiResponse({ status: 400, description: '分页参数格式错误' })
      );
    }
    
    // 控制器中使用
    @Get('user/list')
    @ApiPagination('查询用户列表')
    getUserList() {
      return this.userService.getList();
    }
    
  • DTO复用+CLI插件自动生成字段文档
    所有请求参数、响应结构都用TS类定义为DTO,不要在接口上零散写字段说明。开启@nestjs/swagger的CLI插件后,框架会自动扫描DTO的TS类型、注释、class-validator校验规则,自动生成字段的文档说明,连@ApiProperty装饰器都不用手动写。
    首先在nest-cli.json中开启插件:
    {
      "collection": "@nestjs/schematics",
      "sourceRoot": "src",
      "compilerOptions": {
        "plugins": [
          {
            "name": "@nestjs/swagger",
            "options": {
              "classValidatorShim": true,
              "introspectComments": true
            }
          }
        ]
      }
    }
    
    开启后写DTO只要加普通TS注释就行,Swagger会自动识别:
    export class UserDto {
      /** 用户ID */
      id: number;
      /** 用户昵称 */
      nickname: string;
      /** 账号注册时间 */
      createTime: Date;
    }
    
    通用的分页响应、列表响应这类结构,写一次基础DTO,所有业务接口直接继承复用就行,不用重复定义字段。
入门实用建议
  • 别一开始就折腾静态swagger文件,NestJS体系下动态生成文档的方式和代码绑定更紧,只要改代码的时候同步更新DTO,文档不会和实际接口脱节。
  • 配置遵循公共逻辑全局收,业务逻辑局部写的原则:通用错误码、通用参数、鉴权这类全接口共用的配置全放到初始化逻辑里,只有某个接口特有的错误码、特殊参数才单独在接口上配置。
  • 用@ApiTags()按业务模块给控制器打标签,Swagger页面会自动把同模块接口归组,查找调试都方便。
  • 不用为了文档“看起来全”写一堆无意义的描述,比如200响应默认就是“请求成功”,不用每个接口重复写,只把特殊的业务规则、错误场景写清楚就行。

内容的提问来源于stack exchange,提问作者diabeetus-fairy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:18:14