在 Node.js/Express 中集成 OpenAPI 与 Swagger

在 Node.js 和 Express 项目中使用 swagger-jsdoc 与 swagger-ui-express 暴露 OpenAPI 文档与交互式 Swagger UI。

#tech / dev / backend #type / howto #status / growing

[!info] related notes

在 Node.js/Express 中集成 OpenAPI 与 Swagger

问题

希望在 Node.js / Express 项目中同时得到:

  • 可机读的 OpenAPI JSON
  • 可浏览的 Swagger UI
  • 可随着路由和 schema 持续更新的接口文档

方案

这里采用:

  • swagger-jsdoc 负责从配置和注释生成 OpenAPI 结果
  • swagger-ui-express 负责暴露交互式文档页面

步骤

1. 安装依赖

pnpm add swagger-jsdoc swagger-ui-express
pnpm add -D @types/swagger-jsdoc @types/swagger-ui-express

2. 创建 Swagger 配置文件

swagger.ts

import swaggerJsdoc from 'swagger-jsdoc';
import swaggerUi from 'swagger-ui-express';
import type { Express } from 'express';

const options = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'DailyUse API',
      version: '1.0.0',
      description: 'DailyUse 应用的 REST API 文档',
    },
    servers: [
      {
        url: 'http://localhost:3888/api/v1',
        description: '开发环境',
      },
    ],
    components: {
      securitySchemes: {
        bearerAuth: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'JWT',
        },
      },
      schemas: {
        ApiResponse: {},
        ErrorResponse: {},
      },
    },
  },
  apis: ['./src/modules/**/routes.ts', './src/shared/types/*.ts'],
};

const specs = swaggerJsdoc(options);

export function setupSwagger(app: Express): void {
  app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));

  app.get('/api-docs.json', (_req, res) => {
    res.json(specs);
  });
}

3. 在 Express 应用中挂载

app.ts

import { setupSwagger } from './config/swagger.js';

const app = express();

// Swagger 必须放在路由和 404 处理器之前
setupSwagger(app);

app.use('/api/v1', apiRoutes);

app.use((_req, res) => {
  res.status(404).json({ code: 'NOT_FOUND', message: 'Not Found' });
});

4. 为路由补注释

/**
 * @swagger
 * /auth/login:
 *   post:
 *     tags: [Authentication]
 *     summary: 用户登录
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [username, password]
 *             properties:
 *               username: { type: string, example: "Test1" }
 *               password: { type: string, example: "Llh123123" }
 *     responses:
 *       200:
 *         description: 登录成功
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/ApiResponse'
 */
router.post('/auth/login', loginController);

验证

  • 打开 /api-docs 看 Swagger UI 是否正常渲染
  • 打开 /api-docs.json 看 OpenAPI JSON 是否生成成功
  • 检查新加路由是否出现在文档中

常见问题

404 Not Found

通常是 setupSwagger(app) 放到了 404 处理器之后。

路由扫描失败

通常是 apis 路径写错,导致 swagger-jsdoc 没扫到目标文件。

依赖未安装

确认已经安装:

pnpm add swagger-jsdoc swagger-ui-express @types/swagger-jsdoc @types/swagger-ui-express

TypeScript 模块解析错误

如果项目使用 ESM,导入编译后文件时通常需要显式写 .js 扩展名。

最短记忆方式

OpenAPI 契约是源头,swagger-jsdoc 负责生成,swagger-ui-express 负责展示,Express 里要优先挂载文档路由。

创建于 2026/4/26 更新于 2026/5/27