[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fAzPVEhpK3gwyLq1T0LM1I-HYZg_LAM8qpfdmeMHAar0":3},{"item":4,"related":51},{"id":5,"type":6,"title":7,"slug":8,"summary":9,"body":10,"coverUrl":11,"productScreenshots":12,"productLinks":13,"authorName":14,"authorUrl":15,"authorSubject":16,"category":17,"tags":22,"sourceLabel":39,"sourceName":40,"sourceUrl":41,"status":42,"seoTitle":43,"seoDescription":44,"canonicalUrl":45,"isFeatured":46,"sno":47,"sortOrder":48,"publishedAt":49,"updatedAt":50,"createdAt":50},"ebf1c66c-307a-4aa4-9927-e89b4b103cff","article","Consumer-driven Contract：前端真正依赖的是什么","consumer-driven-contracts-ai-coding","消费者驱动契约把前端真实使用的请求与响应变成可执行约束，减少 AI 同时修改前后端时的接口错位。","## Consumer-driven Contract：前端真正依赖的是什么\n\n前端和后端都说“接口没问题”，系统却仍然可能联调失败。原因是接口文档描述了很多可能字段，但前端真正依赖的字段、错误状态和边界行为并没有被自动保护。Consumer-driven Contract，消费者驱动契约，关注的是消费者实际提出的请求和实际需要的响应。\n\n## 消费者和提供者分别是谁\n\n在 HTTP 场景中，发起请求的一方通常是消费者，返回响应的一方是提供者。消费者测试会描述一个具体交互：请求路径、参数和它需要的最小响应。提供者在自己的环境中验证，确保未来改动不会破坏这个已被使用的约定。\n\n这和只看 OpenAPI 文档不完全一样。OpenAPI 更像一份完整规格，描述资源可能有哪些状态；消费者契约更像“真实使用案例集合”，只关心某个消费者确实依赖的行为。\n\n## AI 编程为什么需要它\n\nAI 可以很快同时修改前端和后端，但也容易让两边各自“合理”：前端期待 `userName`，后端返回 `name`；前端把 404 当空列表，后端却返回错误对象；某个字段只是可选，前端却直接解构使用。\n\n把消费者真实需求写成契约，AI 每次修改都要面对一组可执行的约束。它可以生成接口实现，也可以生成契约测试，但不能只根据自然语言说“应该兼容”。在拆分服务、替换后端或并行开发时，这种约束尤其有价值。\n\n## 契约测试不替代功能测试\n\n契约测试主要检查双方对消息的理解是否一致，不负责证明提供者内部业务逻辑正确，也不覆盖所有用户流程。如果契约本身写错，测试可能稳定地保护错误假设。因此，契约需要来自真实消费者和经过确认的业务场景。\n\n## 一个简单的落地方式\n\n先挑一个最容易被改坏的接口，记录前端真实发送的请求和读取的响应，再让 AI 生成消费者测试和提供者验证。以后修改接口时，先运行这组契约，再决定是否需要迁移或兼容层。\n\nPact 对消费者驱动契约的定义、边界和实践有完整说明，可参考[官方文档](https:\u002F\u002Fdocs.pact.io\u002F)。","\u002Fuploads\u002F2026-09-14\u002F9fcb3348-6f56-4bc2-b10d-64b07ee28aa8.jpg",[],[],"Foundit","https:\u002F\u002Ffoundit.cn","foundit-ai-editorial",{"id":18,"name":19,"slug":20,"description":21},"6179d3b6-dc34-4483-9ded-3cd9f1b37a47","科普","abbreviation","介绍各领域新兴概念",[23,27,31,35],{"id":24,"name":25,"slug":26},"0848beb4-db26-4fb8-b391-f852a11be192","AI编程","ai-coding",{"id":28,"name":29,"slug":30},"144abe77-0dc6-4f66-a176-20bddb1c0bfa","编程","coding",{"id":32,"name":33,"slug":34},"a202d639-99a6-488a-a712-4d4c6ffd7e15","开发","dev",{"id":36,"name":37,"slug":38},"63b56667-dcdb-4b8b-bcbe-c405143a7ec2","测评","test","官方资料","Pact","https:\u002F\u002Fdocs.pact.io\u002F","published","Consumer-driven Contract 是什么？前后端如何避免各说各话","理解消费者驱动契约测试，以及它如何约束 AI 编程中的前后端接口变更。",null,false,60,0,"2026-09-14T00:00:00.000Z","2026-09-14T15:01:48.695Z",[52,60,69],{"id":53,"type":6,"title":54,"slug":55,"summary":56,"coverUrl":57,"authorName":14,"sno":58,"publishedAt":49,"createdAt":59},"1fc136a1-6613-413d-aabd-3d8a3cd03a98","Semantic Diff：代码改了多少行，不等于逻辑改了多少","semantic-diff-ai-code-review","语义差异比较从函数、类和表达式层面理解代码变化，帮助人和 AI 区分真正的逻辑修改与格式噪声。","\u002Fuploads\u002F2026-09-14\u002Fd36cee9f-244c-4c84-9a73-d762934411a2.jpg",51,"2026-09-14T15:01:49.500Z",{"id":61,"type":6,"title":62,"slug":63,"summary":64,"coverUrl":65,"authorName":14,"sno":66,"publishedAt":67,"createdAt":68},"190a2a0d-4b47-40f7-902a-00ac69ce1b15","AI 编程时代，为什么 Git 和 Pull Request 更重要了","ai-coding-git-pull-request-safety-net","AI 让改动出现得更快，也让变化更难凭记忆追踪。本文解释小提交、Pull Request、自动检查和人工批准如何把 AI 编程变成可比较、可验证、可回滚的协作流程。","\u002Fuploads\u002F2026-09-13\u002F95ac3b51-0915-4200-8130-4ba3195fd935.jpg",40,"2026-09-13T00:00:00.000Z","2026-09-13T11:56:01.900Z",{"id":70,"type":6,"title":71,"slug":72,"summary":73,"coverUrl":74,"authorName":14,"sno":75,"publishedAt":49,"createdAt":76},"54d83c94-d588-400d-9d13-42daa20331e2","CAS：文件的身份可以由内容决定","content-addressable-storage-ai-coding","内容寻址存储 CAS 用内容摘要识别文件和构建产物，解释 AI 编程工具、容器和缓存为什么能复用结果。","\u002Fuploads\u002F2026-09-14\u002F3fab23b3-8bcd-4a3b-bf5a-2ab895ce3a10.jpg",41,"2026-09-14T15:01:41.114Z"]