Vibe Coding API 集成:先冻结 OpenAPI 契约,再生成客户端与服务端
直接让 AI 同时写前后端会把字段、错误和鉴权分散在两套代码里。本文用 OpenAPI 契约、示例、兼容性差分与提供者验证建立唯一接口事实源。
本文要点
- 主题聚焦:AI、Vibe Coding、TypeScript
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
把“做一个创建工单接口,前端也接上”交给 AI,常会得到两套看似匹配的代码:前端发送 priority: "high",后端期待数字;前端只处理 400,后端鉴权失败返回 200 加错误字段;分页游标和日期格式则由模型临场决定。它们在同一次对话里可能凑巧能跑,却没有一份独立事实能判断下一次修改是否破坏消费者。
契约优先不是先写一份装饰性 YAML,而是在实现前冻结“线上可观察行为”。REST、GraphQL 与 gRPC 选择帮助确定接口风格;确定使用 HTTP API 后,OpenAPI 文档应成为 AI 生成服务端骨架、客户端类型、mock 和测试的共同输入。
契约要表达语义,不只表达形状
每个 operation 固定稳定 operationId、方法、路径、认证要求、请求参数、成功响应和失败响应。字段除了类型,还要说明必填、可空、默认值、枚举、格式、长度和读写方向。required 与 nullable 是不同问题;字段缺失、显式 null 和空字符串也不能在实现里随意合并。
日期明确为 RFC 3339 时间点还是不含时区的业务日期;金额使用最小货币单位整数或明确精度的字符串,不用二进制浮点暗示精确;ID 定义为不透明字符串,不让客户端推断数据库自增。示例必须通过 schema 校验,而且至少包含一个正常、一个边界与一个错误案例,不能只放漂亮 happy path。
错误建议统一使用稳定机器码、面向用户的安全说明、关联 ID 和可选字段错误。RFC 9457 定义了 HTTP API Problem Details,可以作为传输结构基础,但项目仍要建立自己的 type URI 或错误码治理。不要把数据库错误文本直接写入 detail,也不要要求客户端解析自然语言。
分页、幂等和并发控制同样属于契约。游标是否不透明、下一页为空如何表示、创建接口是否接受幂等键、更新是否要求 ETag/版本,都要在 header 与 response 中声明。版本策略可参考REST API 版本控制,但优先做向后兼容演进,不要把每个字段新增都升级整个 URL。
让 AI 围绕契约分工
第一回合只允许 AI 根据用户故事起草 OpenAPI patch,并列出未决语义;不生成业务代码。开发者与消费者审查操作命名、权限、状态码、字段所有权和错误。确认后锁定规范版本与 hash,第二回合再生成 server interface、验证器和薄客户端。
生成物要可删除重建。不要手改生成的类型;个性化行为放在 wrapper 中,例如认证注入、trace header、超时和领域错误映射。服务端也不能把生成 controller 当业务层,生成层负责解析和响应匹配,领域用例仍执行授权与事务。这样更新生成器不会覆盖核心逻辑。
若手写客户端更简单,也应由契约测试它,而不是复制一套 TypeScript interface。OpenAPI 的 JSON Schema 方言、生成器支持子集和 oneOf 等特性可能不一致,选择语法前用最小探针验证工具链,不要因为规范允许就假设所有工具正确实现。
编程 Agent 修改 API 的契约兼容门可直接纳入 PR:AI 改规范时生成语义 diff,区分新增可选字段与删除字段、收紧枚举、改变必填、改变状态码等破坏性变化。规范和生成物一起提交,CI 重新生成后必须无 diff,避免开发机使用旧生成器。
三层验证防止“文档正确、实现错误”
第一层是规范静态检查:引用可解析、operationId 唯一、每个操作有认证声明和错误响应、示例通过 schema、敏感字段不出现在示例。团队规则可阻止模糊的 object、无界字符串和默认 200 错误。
第二层是提供者验证。启动真实应用,按契约发送请求并校验响应状态、header 和 body;同时覆盖认证失败、校验失败、资源不存在、冲突和限流。仅由框架生成 Swagger 文档不算证明,因为业务中间件仍可能返回契约外 HTML 或字段。契约测试:消费者驱动与提供者验证可帮助决定由谁维护交互样例。
第三层是消费者测试。让前端或集成服务使用生成客户端对 mock 运行,再让同一套关键场景对真实提供者运行。API Mock 与 Fixture 漂移门禁强调 mock、契约与真实实现的三方对齐;mock 不能自行增加真实 API 不存在的便利行为。
故障测试还应注入超时、连接中断、未知错误体、额外字段和旧版响应。客户端对新增字段保持宽容,对缺失必填字段明确失败;错误映射保留原始状态与关联 ID。日志记录 operationId、契约版本和结果类别,而不记录密钥或完整敏感 body。
契约获批的定义不是 YAML 合并,而是规范 lint 通过、生成可重复、兼容性 diff 已审查、提供者和消费者关键交互都能验证。把这份契约作为每次 AI 对话的固定上下文,模型可以高效生成机械代码,同时无法偷偷替双方决定字段和错误语义。
Related