OpenAPI HTTP 契约、校验与兼容治理手册
OpenAPI 描述 HTTP API,使人和工具无需读取实现即可理解服务能力。当前已发布规范主线包含 3.2.0;项目仍要根据工具生态选择明确版本,不能把“latest”写进构建后期待所有解析器同步升级。规范、schema、lint 规则和生成器是四条不同版本轴。
先固定规范与所有权
一份契约需要明确服务 owner、路径范围、版本策略、发布入口和消费者。设计优先与代码生成都可以工作,但必须确定最终事实在哪里:若契约是源,代码和 Mock 从它派生;若实现生成契约,CI 要比较稳定输出并阻止手改生成物。
OpenAPI 3.2 对 HTTP 接口的表达更完整,但旧工具可能只支持 3.0 或 3.1。升级前先验证解析器、文档站、网关、Mock 和代码生成器。版本字段声明的是文档语义,不代表 API 业务版本。
写出最小可验证契约
契约从 info、servers、paths 和 components 建立。每个 operation 使用稳定 operationId,响应覆盖成功与关键错误,schema 明确必填、空值和额外属性策略。示例只使用脱敏数据。
openapi: 3.2.0
info: { title: Checkout API, version: 1.0.0 }
paths:
/orders/{orderId}:
get:
operationId: getOrder
responses:
"200":
description: Order found配置影响包括 JSON Schema 方言、$ref 解析、server 变量、security 继承和 Markdown 渲染。规范允许引用外部资源,工具必须处理循环和不可信远程内容;公开文档还要清洗 description 中可能出现的 HTML。
正向验证从解析走到实现
正向实验先解析与 lint,再 bundle 引用,启动本地 Mock,最后用真实实现跑契约测试。每层回答不同问题:解析证明结构可读,lint 证明符合组织约定,Mock 证明消费者能按描述交互,契约测试才接近实现一致性。
npx spectral lint api/openapi.yaml
npx redocly bundle api/openapi.yaml --output api/dist/openapi.yaml
npx prism mock api/dist/openapi.yaml项目接入 CI 后,PR 运行 lint、bundle 和相对基线的 breaking check;主分支发布带来源提交的不可变契约。工具凭证使用独立身份,预览环境不连接生产数据。
反向实验验证门禁真实存在
反例可以删除一个已发布响应字段、把可选参数改为必填、制造错误 $ref,确认对应门禁失败并指出消费者影响。另一个实验让 Mock 返回合规响应、实现返回另一结构,用来证明 Mock 不代表实现。
故障按文档解析、规则、引用、兼容和运行实现分层。预览正常但 lint 失败通常是组织规则;本机引用成功而 CI 失败多半是路径大小写或远程资源;diff 通过但消费者失败,则要检查工具规则覆盖、媒体类型和业务语义。保留基线契约、候选契约和工具版本,才有可重放证据。
安全、权限与发布边界
契约会暴露路径、字段、认证方式和服务器地址。公开版与内部版应从同一事实源生成受控投影,避免长期维护两份文件。示例禁止真实 Token、Cookie、内网 server、客户标识和生产 payload;security scheme 只描述机制,不保存凭证。
代码生成器和预览器属于供应链工具,可能执行模板或访问远程引用。构建环境限制网络、文件和输出大小,模板升级独立评审。容量与成本关注契约规模、生成耗时、消费者数量和发布版本,不用无限复制 bundle 解决引用治理。
清理、回滚与长期兼容
删除 operation 或 schema 前先查询消费者,发布废弃期和迁移入口。错误契约发布后,优先追加兼容修复;直接覆盖旧版本会破坏审计。工具升级造成大面积格式差异时,回滚版本并把规范语义变化与格式噪声分开评审。
迁移到其他文档平台时保留原始 OpenAPI、bundle、规则集和发布历史。恢复演练要求新环境能解析、lint、预览并执行一项契约测试。退出某个 UI 不难,难的是保住稳定 URL、版本和消费者判断依据。
