> 前后端吵架,90% 不是因为技术分歧,而是因为**契约模糊**和**信息不同步**。
前端说"后端返回少了个字段",后端说"你文档没看全";后端说"前端传参格式不对",前端说"你接口文档里没写清楚是数组还是对象"......这种对话每天都在发生。
所以,高效协作的本质不是"谁技术更牛",而是**把不确定性降到最低**。以下是我总结的 6 条铁律 + 1 套可落地规范。
铁律一:先有契约,后有代码(契约驱动开发)
**现状**:很多团队是后端先写代码,写完了再补 Swagger 文档,前端等着联调时才发现字段对不上。
**规范**:
-
**采用 OpenAPI(Swagger)3.0 作为第一契约**。后端在写 Controller 之前,**先定义好 YAML/JSON 的 Schema**,或者用注解生成精确的文档。
-
**文档必须包含**:每个字段的类型(含 null 是否允许)、取值范围、枚举值列表、错误码清单。
-
**前端依据文档 Mock 数据**,并行开发。后端依据文档写实现。两边都跑通了,再联调。
> 关键动作:**接口评审时,前后端 Leader 同时在场,对着文档逐字段过一遍。** 任何口头约定的"到时候再补"都要写在文档的 TODO 里。
铁律二:统一响应结构(别再各写各的)
最常见的内耗就是每个接口返回格式都不一样。有的用 `code`,有的用 `status`,有的成功不返回 `data`,有的错误把信息塞在 `msg` 里。
**强制规范(直接抄走)**:
```json
{
"code": 0, // 0=成功,非0=业务错误码
"msg": "success", // 友好提示信息
"data": { ... }, // 实际业务数据,成功时必返回
"timestamp": 1700000000, // 时间戳,便于排查
"traceId": "uuid" // 链路追踪ID,方便关联日志
}
```
**细化约定**:
-
成功:`code=0`,`data` 不为 null(若无数据返回空对象 `{}`,而非 null)。
-
业务失败:`code=10001` 等业务码,`msg` 展示给用户看的提示。
-
系统异常(如 500):`code=500`,`msg` 为"系统繁忙",**绝不能把异常堆栈返回给前端**。
前后端各封装好请求/响应拦截器,前端只要判断 `code===0` 就走成功分支,否则统一弹 `msg`。**从此告别 if-else 满天飞判断各种字段名**。
铁律三:版本管理 + 灰度发布(告别"我改了你没更新")
这是吵架重灾区。后端上线新版本改了字段,前端没适配,线上炸了。
**规范**:
-
**接口路径必须带版本号**:`/api/v1/order`、`/api/v2/order`。V1 和 V2 可以共存。
-
**兼容性承诺**:
-
**V1 接口一旦发布,必须向后兼容至少 3 个月**。删除字段必须先标记 `@Deprecated` 并在文档注明,而不是直接删。
-
**新增字段统一加 `@since` 注解**,前端可以按需取用。
-
**发布节奏**:后端先发布新版本接口(V2),前端在合适时机切换。切换期间,V1 依然可用。
铁律四:错误码字典(别再口头传"你抛个啥我接着")
很多项目错误码是随性的,后端抛一个 `-1`,前端就 `alert(-1)`,用户一脸懵。
**规范**:建立**全局错误码 Excel/飞书文档**,由后端统一维护,前端只关心 `code`,根据 `code` 做不同 UI 表现:
| 错误码区间 | 类型 | 前端处理策略 |
|---|---|---|
| 0 | 成功 | 正常渲染 |
| 10000-19999 | 参数校验 | 高亮对应表单控件 |
| 20000-29999 | 权限/登录态 | 跳转登录页 |
| 30000-39999 | 业务限制(如库存不足) | Toast 提示,禁用按钮 |
| 50000+ | 系统内部 | 统一报"系统繁忙",上报日志 |
**关键约定**:前端**不要根据 `msg` 里的中文来做逻辑判断**,只认 `code`。因为 `msg` 可能随时修改文案。
铁律五:联调前置与自测门禁(别把联调当 Debug)
最令人崩溃的是:后端说"写好了",前端一调,发现接口报 500,原因是数据库没数据或者入参没处理。
**规范**:
-
**后端必须提供 Postman/HTTP 文件**(如 `.http` 文件)附带**完整的入参示例**,证明接口在本地可以跑通。
-
**前端必须准备 Mock 数据**,在联调前已经完成所有 UI 渲染和交互逻辑。
-
**联调不是"调试代码",而是"验证契约"**。如果联调时发现字段缺失,那说明契约评审阶段就有遗漏。
铁律六:沟通话术标准化(治吵架的终极武器)
吵架通常始于情绪化的表达。改成结构化反馈后,吵架率直降 80%。
| 场景 | 错误话术(引发战争) | 正确话术(高效解决) |
|---|---|---|
| 字段不对 | "你这返回的啥玩意,少了个字段" | "接口 `/api/v1/order` 在返回 `data.items` 时,契约中要求包含 `skuId`,实际响应里没有,请确认是否遗漏" |
| 格式不对 | "你传的格式不对" | "契约要求 `tags` 是 `Array<string>`,但我收到的是 `"tags": "a,b,c"` 字符串,请按数组格式传" |
| 接口超时 | "你这接口慢死了" | "接口 `/api/v1/search` 在压测环境下响应时间 3.2s,超过约定 500ms,请排查 N+1 查询或加缓存" |
**统一沟通模板**:**接口路径 + 契约字段名 + 预期值 + 实际值 + 业务影响**。不人身攻击,不模糊表述。
附录:前后端协作 RACI 职责表(建议贴墙上)
| 事项 | 前端负责 | 后端负责 | 共同参与 |
|---|---|---|---|
| 接口契约定义 | 评审 | 编写 | ✅ 评审会 |
| Mock 数据 | 根据契约生成 | 不参与 | --- |
| 参数校验 | 做表单级校验(体验) | 做权限/业务级校验(安全) | --- |
| 单元测试 | 测 UI 交互 | 测业务逻辑 | --- |
| 集成联调 | 发起联调请求 | 配合排查 | ✅ 一起看日志 |
| 线上问题定位 | 报 traceId 和 code | 根据 traceId 查日志 | --- |
最后送两句话
-
**契约是法律,文档是圣经。** 任何口头承诺都要落成文字(哪怕是飞书群里@确认)。
-
**优雅的协作,就是让每一方都感到"可预期"。** 当后端知道前端会怎么调,前端知道后端会怎么返,信任就建立起来了。信任一旦建立,代码就不会吵架。