CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
API 设计实战入门/课时/文档与工具
RawBlame
课时目录12 节

API 设计实战入门

  1. 01API 基础
  2. 02HTTP 协议层
  3. 03REST 资源设计
  4. 04错误处理
  5. 05认证
  6. 06授权模型
  7. 07API 安全
  8. 08API 风格
  9. 09架构与集成
  10. 10测试
  11. 11可观测与合规
  12. 12文档与工具

文档与工具

OpenAPI、Postman 与 Stoplight。

30 分钟

文档与工具

这一课你将能做到

  1. 用 OpenAPI 3.0 规范手写或生成 API 文档,并集成 Swagger UI
  2. 使用 Postman 进行 API 测试、Mock 和自动化监控
  3. 建立 API 设计评审流程,用 Stoplight 或类似工具做版本管理和风格统一

为什么要学

代码会过时,文档才是 API 的长期契约。好的文档让前端「自助接入」,不用反复问后端;好的工具链让设计、开发、测试、发布形成闭环。面试常问:怎么管理 API 文档?怎么做 API 评审?

先建立图像

API 文档工作流:

┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐
│  设计     │──►│  评审     │──►│  开发     │──►│  发布     │
│ OpenAPI  │   │ Stoplight │   │ 代码生成  │   │ Swagger   │
│  YAML    │   │  风格检查  │   │ Mock 服务 │   │  UI 文档  │
└──────────┘   └──────────┘   └──────────┘   └──────────┘
     │              │              │              │
     ▼              ▼              ▼              ▼
  契约优先      统一风格       前后端并行      在线文档
  版本管理      命名规范       Mock 联调      实时更新

跟着做

步骤 1:手写 OpenAPI 3.0 规范

# openapi.yaml
openapi: 3.0.3
info:
  title: CodeForge API
  description: 编程学习平台 API 文档
  version: 1.0.0
  contact:
    name: CodeForge Team
    email: api@codeforge.com

servers:
  - url: http://localhost:8080/api
    description: 本地开发
  - url: https://api.codeforge.com/api
    description: 生产环境

tags:
  - name: lessons
    description: 课程管理

paths:
  /lessons:
    get:
      tags:
        - lessons
      summary: 获取课程列表
      description: 分页查询所有课程,支持按学习路径过滤
      operationId: listLessons
      parameters:
        - name: page
          in: query
          description: 页码(0-based)
          schema:
            type: integer
            default: 0
        - name: size
          in: query
          description: 每页大小
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: trackId
          in: query
          description: 学习路径 ID
          schema:
            type: string
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponsePageLesson'
        '400':
          description: 参数错误
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'

    post:
      tags:
        - lessons
      summary: 创建课程
      description: 管理员创建新课程
      operationId: createLesson
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LessonRequest'
      responses:
        '201':
          description: 创建成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponseLesson'
        '403':
          description: 无权限
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'

  /lessons/{id}:
    get:
      tags:
        - lessons
      summary: 获取课程详情
      operationId: getLesson
      parameters:
        - name: id
          in: path
          required: true
          description: 课程 ID
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponseLesson'
        '404':
          description: 课程不存在
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    Lesson:
      type: object
      properties:
        id:
          type: integer
          format: int64
          example: 1
        title:
          type: string
          example: Spring Boot 入门
        slug:
          type: string
          example: spring-boot-intro
        content:
          type: string
        trackId:
          type: string
          example: java-web
        createdAt:
          type: string
          format: date-time

    LessonRequest:
      type: object
      required:
        - title
        - slug
        - trackId
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 100
        slug:
          type: string
          pattern: '^[a-z0-9-]+$'
        trackId:
          type: string
        content:
          type: string

    ApiResponseLesson:
      type: object
      properties:
        code:
          type: integer
          example: 200
        message:
          type: string
          example: success
        data:
          $ref: '#/components/schemas/Lesson'

    ApiResponsePageLesson:
      type: object
      properties:
        code:
          type: integer
        message:
          type: string
        data:
          type: object
          properties:
            content:
              type: array
              items:
                $ref: '#/components/schemas/Lesson'
            page:
              type: integer
            size:
              type: integer
            totalElements:
              type: integer
            totalPages:
              type: integer

    ProblemDetail:
      type: object
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
        detail:
          type: string
        instance:
          type: string
          format: uri

步骤 2:Spring Boot 集成 Swagger UI

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.3.0</version>
</dependency>
@Configuration
public class OpenApiConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("CodeForge API")
                        .version("1.0.0")
                        .description("编程学习平台 API 文档")
                        .contact(new Contact()
                                .name("CodeForge Team")
                                .email("api@codeforge.com")))
                .addSecurityItem(new SecurityRequirement().addList("bearerAuth"))
                .components(new Components()
                        .addSecuritySchemes("bearerAuth",
                                new SecurityScheme()
                                        .type(SecurityScheme.Type.HTTP)
                                        .scheme("bearer")
                                        .bearerFormat("JWT")));
    }
}

启动后访问:http://localhost:8080/swagger-ui/index.html

步骤 3:注解生成文档

@RestController
@RequestMapping("/api/lessons")
@Tag(name = "lessons", description = "课程管理")
public class LessonController {

    @GetMapping
    @Operation(summary = "获取课程列表", description = "分页查询所有课程")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "成功"),
        @ApiResponse(responseCode = "400", description = "参数错误",
                content = @Content(schema = @Schema(implementation = ProblemDetail.class)))
    })
    public ApiResponse<Page<Lesson>> list(
            @Parameter(description = "页码(0-based)") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") int size,
            @Parameter(description = "学习路径 ID") @RequestParam(required = false) String trackId) {
        // ...
    }

    @PostMapping
    @Operation(summary = "创建课程", description = "管理员创建新课程")
    @SecurityRequirement(name = "bearerAuth")
    public ApiResponse<Lesson> create(
            @Valid @RequestBody LessonRequest request) {
        // ...
    }
}

步骤 4:Postman 进阶用法

环境变量管理:

// 环境变量:dev
{
  "baseUrl": "http://localhost:8080/api",
  "token": ""
}

// 环境变量:prod
{
  "baseUrl": "https://api.codeforge.com/api",
  "token": ""
}

测试脚本:

// 登录后自动保存 Token
pm.test("登录成功", function () {
    pm.response.to.have.status(200);
    var jsonData = pm.response.json();
    pm.environment.set("token", jsonData.data.accessToken);
});

// 后续请求自动带 Token
// Authorization: Bearer {{token}}

集合 Runner:批量运行整个集合,生成测试报告。

Mock Server:Postman 可以基于 Collection 创建 Mock 服务器,前端在开发阶段就能调用。

Monitors:定时运行集合,监控 API 可用性,失败时发邮件/Slack 通知。

步骤 5:API 设计评审流程

  1. 设计阶段:用 OpenAPI 写 YAML,提交到 Git
  2. 评审阶段:团队 Review,检查命名、风格、错误码、版本策略
  3. 批准阶段:评审通过后,合并到主分支
  4. 开发阶段:后端按 OpenAPI 实现,前端用 Mock Server 并行开发
  5. 验证阶段:契约测试自动校验实现与文档一致性
  6. 发布阶段:Swagger UI 自动更新,通知相关方

Stoplight 功能:

  • 可视化 OpenAPI 编辑器
  • 风格检查(如「URI 必须用小写」「必须有 description」)
  • 版本管理(Git 集成)
  • Mock Server 托管
  • 文档发布(自定义域名、主题)

讲清楚要点

  1. 契约优先(Contract-First):先写 OpenAPI 文档,再写代码。好处:前后端并行开发、Mock 先行、文档与实现强一致。代码生成(Code-First)适合原型,长期项目推荐契约优先。
  2. OpenAPI 是行业标准:Swagger 是工具集,OpenAPI 是规范。工具会过时,规范会演进,但「用 YAML/JSON 描述 API」这个思想不会变。
  3. 文档要「可执行」:Swagger UI 的「Try it out」让调用方直接在浏览器里测试,比看静态文档高效 10 倍。Postman 的「Generate Code」能生成各种语言的客户端代码。
  4. 版本管理不是备份:OpenAPI 文件要进 Git,变更要有 Commit Message, breaking change 要升版本号。文档的演进历史就是 API 的演进历史。
  5. 评审是质量保险:命名不统一(user_id vs userId)、错误码混乱、版本策略缺失——这些问题在评审阶段发现成本最低,上线后改成本最高。

你可能会懵的地方

  • OpenAPI 和 Swagger 什么关系? Swagger 是 SmartBear 公司的工具集(Swagger UI、Swagger Editor、Swagger Codegen);OpenAPI 是 Linux 基金会的规范(原 Swagger 规范)。Swagger 工具支持 OpenAPI 规范。

  • 手写 YAML 和注解生成哪个好? 手写 YAML:适合契约优先,评审方便,与代码解耦;注解生成:适合代码优先,开发快,但文档和代码耦合。大型项目推荐手写 YAML,小项目/原型可以用注解。

  • Postman 和 Swagger UI 怎么分工? Swagger UI:文档展示 + 简单测试;Postman:复杂测试、自动化、Mock、监控。Swagger UI 给「看文档的人」,Postman 给「调接口的人」。

  • OpenAPI 能生成客户端代码吗? 能。用 openapi-generator 或 swagger-codegen 生成 Java、Python、TypeScript 等客户端 SDK。生成的代码包括模型类、API 调用方法、认证逻辑。

  • 文档和代码不同步怎么办? 契约测试(Spring Cloud Contract)自动校验;CI 中检查 OpenAPI 与代码注解一致性;人工 Review 时对照文档和实现。

错法对照

错法问题正解
文档写在 Word/飞书文档里无法版本管理,无法生成代码,无法测试OpenAPI YAML 进 Git
只有 URL 没有 Schema调用方不知道传什么、返回什么每个接口定义 Request/Response Schema
错误码没有文档调用方不知道怎么处理错误定义 4xx/5xx 的响应格式和错误码表
文档和代码不同步前端按文档开发,结果字段不存在契约测试 + CI 校验
没有版本管理不知道文档什么时候改的、改了什么Git 管理,变更记录,版本号标记

卡点急救

  1. Swagger UI 不显示接口:检查 @Tag、@Operation 注解是否正确,包扫描路径是否包含 Controller。
  2. OpenAPI YAML 语法错误:用 Swagger Editor(editor.swagger.io)在线校验,或 openapi-generator validate 命令。
  3. Postman 集合太大,协作困难:按模块拆分多个 Collection,用 Postman 的 Team Workspace 共享,或导出 JSON 进 Git。

面试常问

  • 怎么管理 API 文档? OpenAPI 规范 + Swagger UI 展示 + Git 版本管理 + 契约测试校验。能讲出「契约优先」和「代码优先」的取舍。

  • Postman 除了调接口还能做什么? 自动化测试(Test Scripts)、Mock Server、性能监控(Monitors)、团队协作(Workspace)、生成客户端代码、API 文档发布。

  • API 设计评审要关注什么? URI 命名规范、HTTP 方法语义、状态码使用、错误响应格式、版本策略、分页设计、安全考虑(认证、授权、限流)。

自测三问

  1. 如果后端改了接口但没更新 OpenAPI 文档,怎么自动发现?
  2. 设计一个「API 评审 Checklist」,包含至少 10 个检查项。
  3. 为什么「契约优先」比「代码优先」更适合大型项目?

小结一句话

文档与工具是 API 的「基础设施」:OpenAPI 定义契约,Swagger 展示文档,Postman 驱动协作,评审流程保障质量;契约优先让前后端从「串行等待」变为「并行开发」。

延伸

  • OpenAPI 3.0 规范
  • SpringDoc OpenAPI
  • Postman 学习中心
  • Stoplight 文档
  • 本 track 完结:建议接下来学习「微服务架构」或「云原生部署」方向。
加载本节练习…
← 上一课可观测与合规