大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
文档与工具
这一课你将能做到
- 用 OpenAPI 3.0 规范手写或生成 API 文档,并集成 Swagger UI
- 使用 Postman 进行 API 测试、Mock 和自动化监控
- 建立 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 设计评审流程
- 设计阶段:用 OpenAPI 写 YAML,提交到 Git
- 评审阶段:团队 Review,检查命名、风格、错误码、版本策略
- 批准阶段:评审通过后,合并到主分支
- 开发阶段:后端按 OpenAPI 实现,前端用 Mock Server 并行开发
- 验证阶段:契约测试自动校验实现与文档一致性
- 发布阶段:Swagger UI 自动更新,通知相关方
Stoplight 功能:
- 可视化 OpenAPI 编辑器
- 风格检查(如「URI 必须用小写」「必须有 description」)
- 版本管理(Git 集成)
- Mock Server 托管
- 文档发布(自定义域名、主题)
讲清楚要点
- 契约优先(Contract-First):先写 OpenAPI 文档,再写代码。好处:前后端并行开发、Mock 先行、文档与实现强一致。代码生成(Code-First)适合原型,长期项目推荐契约优先。
- OpenAPI 是行业标准:Swagger 是工具集,OpenAPI 是规范。工具会过时,规范会演进,但「用 YAML/JSON 描述 API」这个思想不会变。
- 文档要「可执行」:Swagger UI 的「Try it out」让调用方直接在浏览器里测试,比看静态文档高效 10 倍。Postman 的「Generate Code」能生成各种语言的客户端代码。
- 版本管理不是备份:OpenAPI 文件要进 Git,变更要有 Commit Message, breaking change 要升版本号。文档的演进历史就是 API 的演进历史。
- 评审是质量保险:命名不统一(
user_idvsuserId)、错误码混乱、版本策略缺失——这些问题在评审阶段发现成本最低,上线后改成本最高。
你可能会懵的地方
-
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 管理,变更记录,版本号标记 |
卡点急救
- Swagger UI 不显示接口:检查
@Tag、@Operation注解是否正确,包扫描路径是否包含 Controller。 - OpenAPI YAML 语法错误:用 Swagger Editor(editor.swagger.io)在线校验,或
openapi-generator validate命令。 - Postman 集合太大,协作困难:按模块拆分多个 Collection,用 Postman 的 Team Workspace 共享,或导出 JSON 进 Git。
面试常问
-
怎么管理 API 文档? OpenAPI 规范 + Swagger UI 展示 + Git 版本管理 + 契约测试校验。能讲出「契约优先」和「代码优先」的取舍。
-
Postman 除了调接口还能做什么? 自动化测试(Test Scripts)、Mock Server、性能监控(Monitors)、团队协作(Workspace)、生成客户端代码、API 文档发布。
-
API 设计评审要关注什么? URI 命名规范、HTTP 方法语义、状态码使用、错误响应格式、版本策略、分页设计、安全考虑(认证、授权、限流)。
自测三问
- 如果后端改了接口但没更新 OpenAPI 文档,怎么自动发现?
- 设计一个「API 评审 Checklist」,包含至少 10 个检查项。
- 为什么「契约优先」比「代码优先」更适合大型项目?
小结一句话
文档与工具是 API 的「基础设施」:OpenAPI 定义契约,Swagger 展示文档,Postman 驱动协作,评审流程保障质量;契约优先让前后端从「串行等待」变为「并行开发」。
延伸
- OpenAPI 3.0 规范
- SpringDoc OpenAPI
- Postman 学习中心
- Stoplight 文档
- 本 track 完结:建议接下来学习「微服务架构」或「云原生部署」方向。