Swagger 教程

Swagger 教程

Swagger 是一套围绕 OpenAPI 规范的 API 开发工具链,提供 API 文档自动生成、可视化调试、客户端代码生成等功能,是 RESTful API 开发的事实标准工具。

Swagger 是什么

  • OpenAPI 规范:API 描述的标准格式(JSON/YAML),前身是 Swagger 规范
  • Swagger UI:把 OpenAPI 文档渲染成交互式 API 调试页面
  • Swagger Editor:在线编写 OpenAPI 文档的编辑器
  • Swagger Codegen:从文档生成客户端/服务端代码

为什么要用 Swagger

  • 文档与代码同步,减少维护成本
  • 前后端联调效率高(可在线调试)
  • 接口规范统一,团队协作更顺畅
  • 生态丰富:支持 30+ 语言代码生成

基础示例(OpenAPI 3.0)

openapi: 3.0.0
info:
  title: 用户接口
  version: 1.0.0
paths:
  /users:
    get:
      summary: 获取用户列表
      responses:
        "200":
          description: 成功
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"
components:
  schemas:
    User:
      type: object
      properties:
        id: { type: integer }
        name: { type: string }

学习路线

  1. 核心组件与 OpenAPI 规范
  2. 编写第一个文档与实例
  3. Swagger UI 发布与定制
  4. 高级功能与 Codegen
  5. 实战与扩展

Swagger 简介

Swagger 简介

1. 发展历史

2010 年  SmartBear 推出 Swagger 规范
2015 年  捐赠给 OpenAPI Initiative
2017 年  OpenAPI 3.0 发布(重大更新)
2019 年  Swagger 工具链全面支持 OAS3
2021 年  OpenAPI 3.1(兼容 JSON Schema)

2. 核心工具

工具用途
Swagger UI交互式 API 文档页面
Swagger Editor在线编辑与预览文档
Swagger Codegen生成客户端/服务端代码
Swagger Hub云端 API 设计协作平台
Swagger InspectorAPI 调试工具

3. OpenAPI 规范核心

# 三大部分
openapi     版本声明
info        接口元信息(title/version)
paths       所有接口路径定义

# 补充部分
components  可复用组件(schema/parameters)
servers     服务器地址列表
security    认证安全配置
tags        接口分组

4. 与 RESTful 的关系

OpenAPI 是描述 RESTful API 的标准语言,Swagger 是实现工具。REST 是设计风格,OpenAPI 是描述格式,二者结合构成完整的 API 开发流程。

5. 生态集成

  • Spring Boot + springdoc-openapi
  • FastAPI 自动生成 /docs
  • Express + swagger-jsdoc
  • Postman 支持导入 OpenAPI 文档

Swagger 核心组件

Swagger 核心组件

1. Swagger UI

# Swagger UI 把 OpenAPI 文档渲染成交互页面
# 功能:
# - 展示所有接口
# - 在线发起请求调试
# - 查看请求/响应结构
# - 下载文档 JSON/YAML

# 快速体验
# https://petstore.swagger.io

2. Swagger Editor

# 在线编辑器,实时预览文档
# https://editor.swagger.io

# 支持
# - YAML/JSON 双向转换
# - 语法校验与错误提示
# - 自动补全
# - 导出/生成代码

3. Swagger Codegen

# 从 OpenAPI 文档生成代码
# 客户端: Java/JS/Python/Go 等 30+ 语言
# 服务端: Spring/Node/Go 等框架

# 用法
swagger-codegen generate \
  -i api.yaml \
  -l python \
  -o ./client

# 替代工具: OpenAPI Generator(社区维护更活跃)

4. 与框架集成

# Spring Boot
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.5.0</version>
</dependency>
# 访问: http://localhost:8080/swagger-ui.html

# FastAPI(Python 内置)
# 自动生成 /docs 与 /redoc

# Express(Node)
npm install swagger-jsdoc swagger-ui-express

5. 常用注解(Java)

@Operation(summary = "获取用户")
@ApiResponse(responseCode = "200", description = "成功")
@Tag(name = "用户管理")

@Schema(description = "用户实体")
@Parameter(description = "用户 ID")

OpenAPI 规范基础

OpenAPI 规范基础

1. 文档结构

openapi: 3.0.3
info:
  title: 图书管理 API
  description: 图书的增删改查接口
  version: 1.0.0
  contact:
    name: 开发团队
    email: dev@example.com
servers:
  - url: https://api.example.com/v1
tags:
  - name: 图书
paths:
  /books:
    get:
      tags: [图书]
      summary: 获取图书列表
      parameters:
        - name: page
          in: query
          schema: { type: integer }
      responses:
        "200":
          description: 成功
components:
  schemas:
    Book:
      type: object
      properties:
        id: { type: integer }
        title: { type: string }
        author: { type: string }

2. HTTP 方法

paths:
  /books:
    get:     获取列表
    post:    创建
  /books/{id}:
    get:     获取详情
    put:     全量更新
    patch:   部分更新
    delete:  删除

3. 参数类型

# 路径参数
parameters:
  - name: id
    in: path
    required: true
    schema: { type: integer }

# 查询参数
  - name: keyword
    in: query
    schema: { type: string }

# 请求头
  - name: X-Token
    in: header
    schema: { type: string }

# 请求体
requestBody:
  required: true
  content:
    application/json:
      schema:
        $ref: "#/components/schemas/Book"

4. 响应定义

responses:
  "200":
    description: 成功
    content:
      application/json:
        schema:
          type: array
          items:
            $ref: "#/components/schemas/Book"
  "404":
    description: 未找到
  "500":
    description: 服务器错误

5. 数据模型

components:
  schemas:
    User:
      type: object
      required: [name, email]
      properties:
        id:
          type: integer
          readOnly: true
        name:
          type: string
          minLength: 2
          maxLength: 50
        email:
          type: string
          format: email
        role:
          type: string
          enum: [admin, user, guest]
        tags:
          type: array
          items: { type: string }

Swagger 第一个文档

Swagger 第一个文档

1. 编写 YAML 文档

# api.yaml
openapi: 3.0.3
info:
  title: Hello API
  description: 第一个 Swagger 文档
  version: 1.0.0

paths:
  /hello:
    get:
      summary: 问候接口
      responses:
        "200":
          description: 成功返回问候语
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "Hello, Swagger!"

2. 在线预览

# 方式一:Swagger Editor
# 打开 https://editor.swagger.io
# 粘贴 YAML 内容,右侧实时预览

# 方式二:Swagger UI 托管
# 上传到任意静态服务器
# 或使用 https://petstore.swagger.io 测试

3. 本地运行 Swagger UI

# 方式一:npm
npm install -g swagger-ui-dist
npx swagger-ui-dist serve

# 方式二:Node 服务
npm install swagger-ui-express express yamljs

const express = require("express");
const swaggerUi = require("swagger-ui-express");
const YAML = require("yamljs");
const swaggerDocument = YAML.load("./api.yaml");

const app = express();
app.use("/api-docs", swaggerUi.serve,
    swaggerUi.setup(swaggerDocument));
app.listen(3000);
# 访问 http://localhost:3000/api-docs

4. 验证文档有效性

# 在线校验
# https://editor.swagger.io 自动校验

# 命令行校验
npx @apidevtools/swagger-cli validate api.yaml

# 输出
# api.yaml is valid

5. 版本管理建议

  • 文档与代码放同一仓库
  • 接口变更同步更新文档
  • 用 git 记录文档演进
  • CI 中校验文档有效性

Swagger 文档实例

Swagger 文档实例

1. 完整用户管理文档

# user-api.yaml
openapi: 3.0.3
info:
  title: 用户管理 API
  version: 1.0.0
servers:
  - url: http://localhost:3000/api

tags:
  - name: 用户

paths:
  /users:
    get:
      tags: [用户]
      summary: 用户列表
      parameters:
        - name: page
          in: query
          schema: { type: integer, default: 1 }
        - name: size
          in: query
          schema: { type: integer, default: 10 }
      responses:
        "200":
          description: 成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  total: { type: integer }
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/User"

    post:
      tags: [用户]
      summary: 创建用户
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UserCreate"
      responses:
        "201":
          description: 创建成功
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"

  /users/{id}:
    get:
      tags: [用户]
      summary: 用户详情
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: integer }
      responses:
        "200":
          description: 成功
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "404":
          description: 用户不存在

    delete:
      tags: [用户]
      summary: 删除用户
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: integer }
      responses:
        "204":
          description: 删除成功
        "404":
          description: 用户不存在

components:
  schemas:
    User:
      type: object
      properties:
        id: { type: integer, readOnly: true }
        name: { type: string }
        email: { type: string, format: email }
        createdAt: { type: string, format: date-time }
    UserCreate:
      type: object
      required: [name, email]
      properties:
        name: { type: string, minLength: 2 }
        email: { type: string, format: email }

2. 上传下载实例

  /files/upload:
    post:
      summary: 上传文件
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
      responses:
        "200":
          description: 上传成功

  /files/{name}/download:
    get:
      summary: 下载文件
      parameters:
        - name: name
          in: path
          required: true
          schema: { type: string }
      responses:
        "200":
          description: 文件内容
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary

Swagger UI 与文档发布

Swagger UI 与文档发布

1. Swagger UI 特性

# 交互式 API 文档页面
# 特性:
- 接口分组与折叠
- 参数表单自动生成
- "Try it out" 在线调试
- 请求/响应模型展示
- 认证配置(API Key/Bearer)

2. 发布方式

# 方式一:静态托管(构建产物)
npm install swagger-ui-dist
# dist/ 目录即为静态文件
# 把 api.yaml 放入 swagger-initializer.js 引用的路径

# 方式二:容器部署
docker run -p 8080:8080 \
  -e SWAGGER_JSON=/app/api.yaml \
  -v $PWD/api.yaml:/app/api.yaml \
  swaggerapi/swagger-ui

# 方式三:框架集成
# Spring Boot / FastAPI / Express 内置

3. 配置自定义

// swagger-initializer.js 或 setup 参数
window.onload = function() {
  window.ui = SwaggerUIBundle({
    url: "./api.yaml",          // 文档地址
    dom_id: "#swagger-ui",      // 容器
    deepLinking: true,          // 深链接
    persistAuthorization: true, // 持久化认证
    docExpansion: "none",       // 默认折叠
    filter: true,               // 搜索过滤
    showExtensions: true,
    defaultModelsExpandDepth: 1,
  });
};

4. 访问控制

# 文档可能暴露接口信息,生产环境注意:
# 1. 内网/认证后才能访问
# 2. Nginx 增加 Basic Auth
location /api-docs {
    auth_basic "API Docs";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

# 3. 或通过网关统一鉴权

5. 文档发布流程

1. 编写/更新 OpenAPI 文档
2. 本地校验(swagger-cli validate)
3. 构建 Swagger UI 静态资源
4. 部署到文档服务器
5. 配置访问控制
6. CI 中自动更新

Swagger UI 主题样式修改

Swagger UI 主题样式修改

1. CSS 覆盖

/* 自定义 swagger-theme.css */
/* 覆盖默认变量 */
:root {
  --swagger-ui-primary-color: #2c3e50;
  --swagger-ui-header-color: #1a5276;
  --swagger-ui-font: "PingFang SC", sans-serif;
}

/* 顶部栏样式 */
.swagger-ui .topbar {
  background: #2c3e50;
  padding: 12px;
}
.swagger-ui .topbar .download-url-wrapper input {
  border: 1px solid #3498db;
}

/* 操作按钮 */
.swagger-ui .btn.authorize {
  background: #3498db;
  color: #fff;
}
.swagger-ui .opblock {
  border-radius: 6px;
}

/* 方法颜色 */
.swagger-ui .opblock-get .opblock-summary {
  border-color: #27ae60;
}
.swagger-ui .opblock-post .opblock-summary {
  border-color: #2ecc71;
}
.swagger-ui .opblock-delete .opblock-summary {
  border-color: #e74c3c;
}

2. 引入自定义样式

<!-- index.html 中引入 -->
<link rel="stylesheet"
      href="./swagger-theme.css">

# 或使用社区主题包
# swagger-ui-themes
npm install swagger-ui-themes

# 常用主题: flattop / material / feeling-blue

3. 修改页面结构

// 通过 SwaggerUIBundle 配置
window.ui = SwaggerUIBundle({
  url: "./api.yaml",
  dom_id: "#swagger-ui",
  // 自定义布局
  layout: "BaseLayout",
  // 显示请求头
  showRequestHeaders: true,
});

4. 自定义页头

<!-- 修改 swagger-initializer.js 前插入自定义导航 -->
<div class="custom-header">
  <h1>公司 API 文档</h1>
  <a href="/">返回官网</a>
</div>

5. 主题定制技巧

  • 用浏览器 DevTools 查看 Swagger UI 的 class 名
  • 覆盖 CSS 变量比逐条改更高效
  • 注意 !important 的使用场景
  • 多环境(测试/生产)用不同主题色区分

Swagger UI 导出文档

Swagger UI 导出文档

1. 导出格式

# Swagger UI 支持导出:
- JSON(OpenAPI 文档)
- YAML(OpenAPI 文档)
- Markdown(人工整理)

# 导出方式
# 1. Swagger UI 页面的下载按钮
# 2. 直接访问文档源文件

2. 获取原始文档

# 如果配置了 url 参数
curl http://localhost:3000/api.yaml

# FastAPI
curl http://localhost:8000/openapi.json

# Spring Boot
curl http://localhost:8080/v3/api-docs

3. 转换工具

# JSON ↔ YAML 转换
npx swagger-cli convert api.yaml -o api.json
npx swagger-cli convert api.json -o api.yaml

# 合并多个文档
npx swagger-cli bundle api.yaml -o bundled.yaml

# 生成 HTML 静态文档(Redoc)
npx redoc-cli bundle api.yaml -o docs.html

# 导出 PDF
# 用浏览器打印 HTML 文档为 PDF

4. Markdown 导出

# 使用 swagger-to-markdown 或手动整理
npm install -g swagger-to-markdown
swagger-to-markdown api.yaml -o api.md

# 或使用 widdershins
npx widdershins api.yaml -o api.md
# 生成三栏式 Markdown 文档

5. 文档归档建议

  • 每个发布版本导出并归档 OpenAPI 文档
  • 离线场景提供 HTML 静态文档
  • Markdown 版本用于内部评审
  • 保持导出与线上文档一致

Swagger 高级功能

Swagger 高级功能

1. 认证与安全

openapi: 3.0.3
info: { title: 安全 API, version: 1.0.0 }

# 认证方式定义
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    basicAuth:
      type: http
      scheme: basic
    oauth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth.example.com/token
          scopes:
            read: 读取权限
            write: 写入权限

# 全局应用
security:
  - bearerAuth: []

# 或按接口应用
paths:
  /admin:
    get:
      security:
        - bearerAuth: [write]

2. 请求示例与响应示例

components:
  examples:
    userExample:
      summary: 用户示例
      value:
        id: 1
        name: 张三
        email: zhang@example.com

paths:
  /users:
    get:
      responses:
        "200":
          content:
            application/json:
              examples:
                default:
                  $ref: "#/components/examples/userExample"

3. 枚举与约束

properties:
  status:
    type: string
    enum: [active, inactive, deleted]
  age:
    type: integer
    minimum: 0
    maximum: 150
  name:
    type: string
    pattern: "^[a-zA-Z\u4e00-\u9fa5]+$"
  score:
    type: number
    multipleOf: 0.5

4. 回调与 Webhook

paths:
  /subscribe:
    post:
      summary: 订阅事件
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                callbackUrl:
                  type: string
                  format: uri
      callbacks:
        onEvent:
          "{$request.body#/callbackUrl}":
            post:
              summary: 事件回调
              requestBody:
                content:
                  application/json:
                    schema:
                      type: object
                      properties:
                        event: { type: string }
                        data: { type: object }

5. 多服务器与多环境

servers:
  - url: https://api.example.com/v1
    description: 生产环境
  - url: https://staging.example.com/v1
    description: 测试环境
  - url: http://localhost:3000/api
    description: 本地开发
    variables:
      port:
        enum: [3000, 8080]
        default: 3000

Swagger Codegen

Swagger Codegen

1. 什么是 Codegen

Swagger Codegen 根据 OpenAPI 文档自动生成客户端 SDK 或服务端骨架代码,消除手工编写重复代码的工作。

2. 安装

# 在线版本(推荐)
# https://generator.swagger.io

# CLI 安装
# 下载 swagger-codegen-cli jar
wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.52/swagger-codegen-cli-3.0.52.jar

# 或使用 OpenAPI Generator(社区版)
npm install @openapitools/openapi-generator-cli -g

3. 生成客户端代码

# Python 客户端
java -jar swagger-codegen-cli.jar generate \
  -i api.yaml \
  -l python \
  -o ./python-client

# JavaScript 客户端
java -jar swagger-codegen-cli.jar generate \
  -i api.yaml \
  -l javascript \
  -o ./js-client

# OpenAPI Generator(Python)
openapi-generator-cli generate \
  -i api.yaml \
  -g python \
  -o ./client

4. 生成服务端代码

# Spring Boot 服务端
openapi-generator-cli generate \
  -i api.yaml \
  -g spring \
  -o ./server

# FastAPI 服务端
openapi-generator-cli generate \
  -i api.yaml \
  -g python-fastapi \
  -o ./fastapi-server

# Node Express
openapi-generator-cli generate \
  -i api.yaml \
  -g nodejs-express-server \
  -o ./node-server

5. Codegen 最佳实践

# 1. 文档先行:先定义 OpenAPI 再生成代码
# 2. 代码生成目录与手工代码分离
# 3. 避免修改生成代码(用扩展机制)
# 4. 生成代码加入 .gitignore 或单独仓库
# 5. CI 中自动化生成

# 自定义模板
openapi-generator-cli generate \
  -i api.yaml -g python \
  -t ./my-templates \
  -o ./client

# 全局配置
openapi-generator-cli config-help -g python
openapi-generator-cli generate -i api.yaml \
  -g python -c config.json -o ./client

Swagger 实战教程

Swagger 实战教程

1. FastAPI + Swagger 实战

# FastAPI 自动生成 OpenAPI 文档
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI(
    title="图书管理 API",
    description="图书增删改查接口",
    version="1.0.0",
)

class Book(BaseModel):
    id: int
    title: str
    author: str
    price: float

books = [
    Book(id=1, title="Python 入门", author="张三", price=59.0),
]

@app.get("/books", tags=["图书"])
async def list_books():
    """获取图书列表"""
    return books

@app.post("/books", tags=["图书"], status_code=201)
async def create_book(book: Book):
    """创建图书"""
    books.append(book)
    return book

@app.get("/books/{book_id}", tags=["图书"])
async def get_book(book_id: int):
    """获取图书详情"""
    for b in books:
        if b.id == book_id:
            return b
    raise HTTPException(404, "图书不存在")

# 访问: http://localhost:8000/docs(Swagger UI)
#       http://localhost:8000/redoc(Redoc)

2. Spring Boot 集成

// 添加依赖 springdoc-openapi
// 配置类
@Configuration
@OpenAPIDefinition(
    info = @Info(title = "用户 API", version = "1.0.0"),
    servers = @Server(url = "/api")
)
public class OpenApiConfig {}

// Controller 注解
@RestController
@RequestMapping("/api/users")
@Tag(name = "用户管理")
public class UserController {

    @GetMapping
    @Operation(summary = "用户列表")
    public List<User> list() { ... }

    @PostMapping
    @Operation(summary = "创建用户")
    @ApiResponse(responseCode = "201", description = "创建成功")
    public User create(@RequestBody @Valid User user) { ... }
}

// 访问: http://localhost:8080/swagger-ui.html

3. Express + swagger-jsdoc

npm install swagger-jsdoc swagger-ui-express

const swaggerJsdoc = require("swagger-jsdoc");
const swaggerUi = require("swagger-ui-express");

const options = {
  definition: {
    openapi: "3.0.0",
    info: { title: "用户 API", version: "1.0.0" },
  },
  apis: ["./routes/*.js"],   // 扫描注释
};

const swaggerSpec = swaggerJsdoc(options);
app.use("/api-docs", swaggerUi.serve,
    swaggerUi.setup(swaggerSpec));

// routes/users.js
/**
 * @swagger
 * /users:
 *   get:
 *     summary: 用户列表
 *     responses:
 *       200:
 *         description: 成功
 */
router.get("/users", ...);

4. 文档与测试结合

# 用 OpenAPI 文档做契约测试
# pytest + schemathesis
pip install schemathesis

schemathesis run http://localhost:8000/openapi.json \
  --checks all

# 自动根据文档生成测试用例
# 覆盖边界、格式、响应码验证

Swagger 扩展学习

Swagger 扩展学习

1. 知识回顾

  • OpenAPI 规范:API 描述标准(JSON/YAML)
  • Swagger UI:交互式文档与调试界面
  • Swagger Editor:在线编辑与校验
  • Swagger Codegen:代码自动生成
  • 生态集成:Spring/FastAPI/Express/Postman

2. 进阶方向

  • OpenAPI 3.1:兼容 JSON Schema 的新特性
  • AsyncAPI:异步/事件驱动 API 规范
  • JSON Schema:数据校验标准
  • 契约测试:文档驱动的测试体系
  • API 网关:Kong/Apisix 集成 OpenAPI

3. 官方资源

OpenAPI 规范:  spec.openapis.org
Swagger 官网:  swagger.io
Swagger 工具:  github.com/swagger-api
OpenAPI 生成器: openapi-generator.tech
在线编辑器:    editor.swagger.io
演示环境:      petstore.swagger.io

4. 常见问题

# Q: YAML 报缩进错误?
# A: 用 editor.swagger.io 自动检测,注意 2 空格缩进

# Q: 文档与代码不同步?
# A: 用框架注解自动生成(FastAPI/springdoc)

# Q: 接口变更如何管理?
# A: OpenAPI 版本号 + 变更日志,或 API 版本化(/v1 /v2)

# Q: 如何保护文档?
# A: Nginx Basic Auth / 网关鉴权 / 内网部署

5. 实践建议

  1. 新项目从 OpenAPI 文档开始(Design First)
  2. 老项目用框架自动生成(Code First)
  3. 把文档纳入 CI 校验
  4. 用 Swagger UI 加速前后端联调
  5. 定期导出归档文档版本

Swagger/OpenAPI 是现代 API 开发的必备技能,掌握后能显著提升接口开发与协作效率。

第 1 / 13 节