API 契约与生产运行:OpenAPI、版本化和可观测
0. 元信息
- 主题路径:
docs/topics/rest-api-design/subtopics/openapi-operations/README.md - 父主题:
rest-api-design - 主分类:Web 与后端
- 辅助分类:工程技术
- 适合对象:会写 HTTP handler、SQL 与自动化测试的后端开发者
- 建议周期:1~2 周(每周 6~8 小时)
- 前置知识:
resource-http-contracts、security-governance、performance-delivery - 最终目标:覆盖 OpenAPI 3.1、JSON Schema、兼容演进、文档工具、日志指标 tracing
1. 学习路线
OpenAPI → lint/mock/SDK → compatibility → versioning → deploy → logs/metrics/tracing
2. 阶段周数分配
精简子主题不固定周数。按 §3 顺序完成,卡住时回到 RFC、契约样例和可重复请求。
3. 九阶段表
| 阶段 | 核心知识 | 实践产出 | 学会标准 |
|---|---|---|---|
| 1 | 术语与边界 | 术语表 | 不混淆相邻概念 |
| 2 | HTTP/标准语义 | 请求矩阵 | 能引用规范解释 |
| 3 | 数据与状态 | schema/状态图 | 正常与冲突可区分 |
| 4 | 安全边界 | 威胁清单 | 非法路径被拒绝 |
| 5 | 失败语义 | 错误目录 | 客户端能稳定处理 |
| 6 | 兼容策略 | 变更表 | 能识别 breaking change |
| 7 | 工具验证 | curl/collection | 可重复运行 |
| 8 | 自动检查 | 契约测试 | 修改后会报警 |
| 9 | 小项目 | 可运行交付 | 第三方可复现 |
4. 第一周任务
精简版省略固定日程。做一个最小正常请求,再补认证失败、非法输入、冲突、重试与超时。
5. 阶段通用验收
精简版省略;每个产出至少保留命令、预期、实际与版本。
6. 最终验收
精简版省略;以 §3 第 9 阶段和 §9.4 问题口述检查为准。
7. 综合项目
精简版省略;成果并入父主题电商商品 / 订单 API。
本主题贡献
- 在父主题
rest-api-design的综合项目「电商商品 / 订单 API」中,本主题(API 契约与生产运行)负责 OpenAPI 3.1 主契约 + lint + mock + 客户端 SDK + 兼容演进 + 可观测:把 §1 路线「OpenAPI → lint/mock/SDK → compatibility → versioning → deploy → logs/metrics/tracing」落到 CI/CD 管线里,作为整个电商 API 唯一的真相源。 - 工程动作:用 OpenAPI 3.1 作为唯一契约源(聚合 resource-http-contracts、security-governance、performance-delivery 三块);用
.spectral.yaml+spectral lint+redocly lint+openapi-spec-validator在 CI 拦下oas3-api-servers / operation-operationId / oas3-valid-media-example等错误;用oasdiff breaking base/openapi.yaml openapi.yaml与 Redocly diff 出 breaking change 报告;用@stoplight/prism-cli mock提供前端独立联调环境;用openapi-generator-cli生成 TypeScript-Fetch 与 Go 客户端到clients/ts、clients/go;用 Schemathesis 跑契约测试 ≥ 200 例;用 W3Ctraceparent+tracestate跨 Webhook 串联 traceid。 - 与 rest-api-design 其它子主题对接:聚合其它三个子主题的 OpenAPI 成
oas/main.yaml;产出发布清单(lint 0 error、breaking 0、SDK 已发 tag、runbook 与 examples 对齐、旧版本路由 deprecation 头);保障 traceid 通过traceparent头贯穿 Webhook 与日志。
交付物清单:
oas/main.yaml:OpenAPI 3.1 主契约(聚合 3 个子主题),含components.securitySchemes、webhooks、x-codeSamples、x-tagGroups;oas/.spectral.yaml+ CI 截图:spectral / redocly / openapi-spec-validator三个 lint 全通过;CI 跑完 0 error;clients/ts/+clients/go/:openapi-generator生成 TS-Fetch + Go 客户端,含单元测试 1 个示例调用(含traceparent头与Idempotency-Key);compat/diff.md+release-checklist.md:oasdiff breaking报告 + 发布清单 8 条(含 SDK tag、deprecation 头、trace 串联、Spectral 0 error、Schemathesis 抽样、runbook 与 examples 对齐)。
验收标准:
spectral lint/redocly lint/openapi-spec-validator三个 0 error;oasdiff breaking检测在 5 个模拟 PR 上 0 误报,类型 / 字段删除 / 路径删除均可识别;- Schemathesis 用
--hypothesis-max-examples=200抽样全 operation,0 unexpected; - 客户端 SDK demo 跑一次成功,traceid 通过
traceparent头贯穿 Webhook、MQ headers 与日志; - 旧 major 在网关被路由到旧服务并打 deprecation 头(
Deprecation: true/Sunset: <date>),新 SDK 只调用新 major。
8. 推荐资料
精简版省略;使用 §9.3 和 §9.6 Source。
9. 学习资料汇聚(v0.3 自包含)
9.1 背景与动机
覆盖 OpenAPI 3.1、JSON Schema、兼容演进、文档工具、日志指标 tracing。API 一旦被客户端依赖,错误的语义会变成多年兼容成本。我们用规范、可运行样例和失败测试约束选择。
9.2 概念地图
flowchart LR
Design[设计] --> Contract[HTTP/OpenAPI 契约]
Contract --> Runtime[实现/网关]
Runtime --> Client[客户端]
Runtime --> Evidence[日志/指标/trace]
Test[契约与失败测试] -.验证.-> Contract
Test -.验证.-> Runtime
这张图把设计、实现、调用和证据串起来。任何规则都要能落到契约或运行时检查。
9.3 基础知识讲解
9.3.1 论文 / 规范
- Roy Fielding, Architectural Styles and the Design of Network-Based Software Architectures:REST 起源。
- RFC 9110, HTTP Semantics:方法、状态码、缓存语义。
- RFC 7807, Problem Details for HTTP APIs:统一错误对象。
9.3.2 书
- Leonard Richardson, Mike Amundsen, Sam Ruby, RESTful Web APIs。
- Arnaud Lauret, The Design of Web APIs。
- JJ Geewax, API Design Patterns。
9.3.3 博客 / 文档
- Stripe API 文档:idempotency、分页、错误风格。
- Microsoft REST API Gui:兼容与一致性。
- Google API Design Guide:资源导向设计。
- Apigee 文档 与 AWS API Gateway 文档:网关、配额、部署。
9.3.4 人物
- Roy Fielding:REST 与 HTTP 架构。
- Tim Berners-Lee:Web、URI、HTTP。
- Darrel Miller:OpenAPI Initiative 技术治理与工具生态。
9.3.5 方法
- Contract-first:先写 OpenAPI 和示例,再写 handler。
- Consumer-driven review:从调用方任务检查命名、错误和兼容。
- Single-variable test:一次只改变 method、header、身份或并发量。
- Compatibility budget:发布前列出 breaking change 与迁移期。
9.4 经典问题与经典案例
| 问题 | 为什么重要 | 最简答案 |
|---|---|---|
| contract-first 还是 code-first | 影响客户端正确性和长期兼容 | 写清语义、失败码、重试与测试证据 |
| 什么算 breaking change | 影响客户端正确性和长期兼容 | 写清语义、失败码、重试与测试证据 |
| 版本放 path 还是 header | 影响客户端正确性和长期兼容 | 写清语义、失败码、重试与测试证据 |
| 如何避免文档漂移 | 影响客户端正确性和长期兼容 | 写清语义、失败码、重试与测试证据 |
| trace id 如何跨 Webhook | 影响客户端正确性和长期兼容 | 写清语义、失败码、重试与测试证据 |
| P99 高如何分层定位 | 影响客户端正确性和长期兼容 | 写清语义、失败码、重试与测试证据 |
9.4.1 实战片段:lint、breaking change、SDK、trace
# .spectral.yaml —— 团队 lint 规则
extends: ["spectral:oas"]
rules:
oas3-api-servers: error
operation-operationId: error
operation-description: warn
oas3-valid-media-example: error
info-contact: off
info-license: off
# 1. 校验契约
spectral lint openapi.yaml --ruleset .spectral.yaml
redocly lint openapi.yaml
openapi-spec-validator openapi.yaml
# 2. 看 breaking change
oasdiff breaking base/openapi.yaml openapi.yaml
npx @redocly/cli diff base/openapi.yaml openapi.yaml --format=markdown > diff.md
# 3. mock server(前端独立联调)
npx @stoplight/prism-cli mock openapi.yaml --port 4010
# 4. 生成客户端
openapi-generator-cli generate \
-i openapi.yaml -g typescript-fetch -o clients/ts \
--additional-properties=supportsES6=true,npmName=@acme/api-client
openapi-generator-cli generate \
-i openapi.yaml -g go -o clients/go \
--additional-properties=packageName=apiclient
# 5. Dredd / Schemathesis 契约测试
dredd openapi.yaml https://api.example.com --hookfiles=./hooks.js
schemathesis run openapi.yaml --base-url=https://staging.example.com \
--checks all --hypothesis-max-examples=200
# 6. 兼容演进对照(伪 diff)
POST /v1/orders -> POST /v2/orders # breaking:先并行 6 个月再切
order.id:int -> order.id:string # breaking:类型变更
order.items[] -> + order.discounts # 兼容:新增字段
+ order.taxRate # 兼容:新增字段
- order.legacyCode # breaking:删除字段
# 7. trace context:跨 Webhook、消息、异步任务
curl -i -X POST https://api.example.com/orders \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ...' \
-H 'Idempotency-Key: 9f2b6c1a-1f3d-4b8e-9b6c-2a7f0b5c91a2' \
-H 'traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01' \
-H 'tracestate: acme=t61rcWkgMzE' \
-d '{"productId":"p_1","quantity":2}'
# Webhook 投递时把 traceparent 透传给接收端
curl -X POST https://receiver.example.com/webhook \
-H 'Content-Type: application/json' \
-H 'X-Signature: sha256=...' \
-H 'traceparent: 00-0af7651916cd43dd8448eb211c80319c-c3b8f1c5b6a0d2e0-01' \
-d @payload.json
# 8. 发布 checklist(CI 跑完后人工/自动确认)
- spectral lint:0 error
- oasdiff breaking:0 行
- schemathesis 抽样:0 unexpected
- 客户端 SDK 已发布 tag,CI 引用的是 digest
- runbook 与 OpenAPI 的 examples 一致
- 旧 major 在网关被路由到旧服务并打 deprecation 头
9.5 学习难点
9.5 学习难点
- 概念难点:规范术语相近。卡点来自用框架默认值代替 HTTP 语义;回 RFC 和 wire example。
- 思维难点:正常流很短,重试、并发、权限和演进才难;先列状态机与不变量。
- 工程难点:网关、应用、数据库和客户端行为不同;用端到端请求、契约测试和 trace 定位边界。
9.6 技术标准与接口
9.6.1 Entity
| 名称 | 版本 | 组织 | 状态 / 可访问性 |
|---|---|---|---|
| OpenAPI Specification | 3.1 | OpenAPI Initiative | 正式;Apache-2.0 仓库,规范公开 |
| JSON:API | 1.1 | JSON:API 社区 | 正式;公开 |
| JSON Schema | 2020-12 | JSON Schema / IETF 社区 | 正式;公开 |
| Problem Details for HTTP APIs | RFC 7807 | IETF | 已被 RFC 9457 更新;RFC 公开 |
| HAL | draft-kelly-json-hal | IETF Internet-Draft / HAL 社区 | 草案;公开 |
9.6.2 Scope
OpenAPI 描述 HTTP API;JSON Schema 描述数据约束;JSON:API 与 HAL 约定表示和链接;Problem Details 约定机器可读错误。它们不替代业务授权、事务设计或运行时保护。
9.6.3 Structure
OpenAPI 必会 paths、operations、parameters、requestBody、responses、components、securitySchemes;JSON Schema 必会 type、required、properties、组合与引用;Problem Details 必会 type/title/status/detail/instance。
9.6.4 Ecosystem
实现与工具包括 Swagger UI、Redoc、Spectral、OpenAPI Generator、Postman、Insomnia、Bruno、httpie、curl。API gateway 常用 Apigee、AWS API Gateway、Kong、Envoy。工具默认值不是规范。
9.6.5 Depth Tiers
| 层级 | 可观察能力 |
|---|---|
| L0 | 知道这些标准解决什么问题 |
| L1 | 看懂 schema、operation 和 problem body |
| L2 | 能正确编写、校验、生成客户端并调用 |
| L3 | 能解释语义、排错兼容/鉴权/缓存/限流问题 |
| L4 | 能设计扩展、治理规则与跨团队演进机制 |
本计划目标:L3。
9.6.6 Source
- OpenAPI Initiative 仓库:OpenAPI 3.1 原文与版本历史。
- IETF RFC Editor:RFC 9110、7807/9457、6585 等原文。
- JSON Schema 2020-12 与 JSON:API 1.1。
- 引用快照:2026-07-30。实施前检查更新、勘误与废止关系。
10. 常见误区
- 用框架默认值代替明确契约
- 只测 2xx
- 错误 body 无稳定 code
- 混淆认证与授权
- 重试无 idempotency
- 缓存 key 漏身份/查询条件
- 版本化代替兼容设计
- 文档与实现分开维护
- 日志泄露 secret
- 只有 dashboard,没有可定位的 trace。
11. 所有知识点分类(统一规则)
- 编程语言 2. 数据结构与算法 3. 计算机基础 4. 工程技术 5. Web 与后端 6. 前端与客户端 7. 数据与人工智能 8. 项目与职业能力 9. 安全与可靠性
本计划归属:Web 与后端 主 + 工程技术 辅。