2、契约驱动开发(CDC)哲学:从代码优先到契约优先的思维转变,CDC工作流

说实话,我刚入行那几年,团队做API开发基本都是「代码优先」的路子。后端同学先写接口,跑起来,再扔给前端。前端一看,字段名不对,返回结构也不对,得,改吧。一来二去,联调时间比开发时间还长。后来我接触了契约驱动开发(Contract-Driven Development,简称CDC),才意识到——我们一直在用错误的方式协作。

这一章,我就跟你聊聊CDC的核心哲学,以及它到底怎么改变我们的工作流。

2.1 代码优先 vs 契约优先:两种思维的对决

先看一个对比表格,把两种模式摆到台面上。

维度 代码优先(Code-First) 契约优先(Contract-First)
起点 从实现代码开始 从数据契约定义开始
协作顺序 后端先写 → 前端再对接 前后端并行开发
变更成本 联调时发现问题,改代码 契约评审阶段发现问题,改文档
文档一致性 容易代码与文档脱节 契约即文档,天然一致
测试介入时机 代码完成后才能写测试 契约定义后即可生成Mock测试
典型痛点 联调地狱、字段遗漏、类型不匹配 初期定义需要更多讨论

你想想看,代码优先就像盖房子先砌砖,再画图纸。砌到一半发现窗户位置不对,拆了重砌。契约优先呢?先画好图纸,各方确认,再按图施工。哪个更靠谱?

核心转变:从「先写代码再沟通」变成「先沟通再写代码」。契约是团队之间的承诺,代码只是承诺的实现。

2.2 CDC工作流:五步走,步步为营

我在项目中落地CDC时,总结了一套五步工作流。每一步都有明确的产出物和检查点。

  1. 定义契约 — 用OpenAPI、GraphQL Schema或Protobuf编写数据契约。
  2. 评审契约 — 前后端、QA、产品一起过,确认字段、类型、边界条件。
  3. 生成Mock — 基于契约自动生成Mock Server,前端和测试可以先行。
  4. 实现代码 — 后端按契约实现API,前端按契约调用API。
  5. 验证契约 — 用契约测试工具(如Pact、Spring Cloud Contract)验证实现是否遵守契约。

下面这张图,把整个流程串起来了。

CDC 五步工作流 ① 定义契约 ② 评审契约 ③ 生成Mock ④ 实现代码 ⑤ 验证契约 评审不通过 → 返回修改契约 并行开发阶段 前端:基于Mock开发UI → 编写契约测试 后端:按契约实现API → 通过契约测试验证

我的经验:第三步「生成Mock」是CDC的甜区。我曾经在一个项目中,前端在Mock阶段就发现了3个字段缺失和2个类型错误。如果等到联调才发现,至少多花两天时间。

2.3 契约优先带来的三个关键变化

思维转变不是喊口号,它会在日常工作中体现出来。我总结了三个最明显的变化。

  • 沟通方式变了。以前是「你接口写好了吗?我调一下看看」。现在是「契约发你了,你看看字段对不对」。沟通从「事后验证」变成「事前确认」。
  • 测试左移了。契约定义完,Mock和契约测试就能写。测试不再等代码,而是驱动代码。我记得有个团队,契约测试覆盖率从0%直接跳到85%,联调时间缩短了60%。
  • 文档自动生成了。契约本身就是文档。用OpenAPI定义的契约,可以直接生成Swagger UI。代码改了,契约没改?契约测试会直接报红。文档和实现永远一致。

注意:契约优先不是银弹。如果团队没有契约评审的习惯,或者契约定义过于复杂,反而会增加前期负担。我建议从一个小模块开始试点,跑通流程后再推广。

2.4 避坑指南:我曾经踩过的三个坑

光说好处不够,我也得跟你分享一些教训。

  • 坑一:契约定义太细。我曾经把每个字段的枚举值、长度限制、正则表达式全写进契约。结果评审时吵了三天,因为前端觉得某些校验太严格。后来我学乖了:契约只定义接口形状和核心约束,业务校验留给实现层。
  • 坑二:契约版本管理混乱。有一次,后端改了契约但没通知前端,前端还在用旧版本Mock。联调时发现字段对不上,排查了半天。后来我们强制要求:契约文件必须走Git,每次变更必须提PR,评审通过才能合并。
  • 坑三:Mock数据太完美。Mock Server返回的数据永远是200,字段永远不为空。前端开发时没考虑异常情况,上线后遇到空指针直接崩了。现在我会在Mock中注入一些边界数据:空数组、null字段、超长字符串。

2.5 什么时候该用契约优先?

不是所有项目都适合契约优先。我列了几个判断条件,你可以对照看看。

场景 推荐模式 理由
前后端分离,团队独立 契约优先 减少联调依赖,并行开发
微服务架构,服务间调用多 契约优先 契约测试保障服务兼容性
快速原型,需求不明确 代码优先 快速验证,契约定义成本高
内部工具,只有一个人维护 代码优先 没必要增加流程负担

说白了,契约优先适合「多人协作、接口稳定、质量要求高」的场景。如果你一个人写全栈,或者项目还在探索期,代码优先反而更灵活。

一句话总结:契约优先不是让你多写代码,而是让你少改代码。把沟通成本前置,把返工成本后置。这笔账,算得过来。