后端开发规范
后端开发规范管两件事:代码怎么分层,以及对外的契约长什么样。Harness 生成代码的速度很快,约束不明确时,同一个项目里会同时出现两三套接口风格与响应结构;每多一套,调用方就多一处分支判断,而分支判断是后期最难删除的一类代码。
1这一页管什么
分层与契约是本页的核心;授权判定与日志字段不在这里。
- 管服务端的结构与契约。分层与依赖方向、接口命名与版本控制、请求与响应结构、错误码体系、校验位置、数据访问与事务边界、幂等与并发、配置的读取方式。
- 不交由这一页。谁能访问哪一条资源属安全开发规范;日志字段与指标属部署运维规范;前端如何调用接口属产品设计规范。
- 两种落法。本页绝大多数条目是常驻约束,写进规则;「按规范加一个接口」「按规范做一次数据迁移」这类流程写成技能。
对应的课程知识点:软件设计中的信息隐藏与依赖倒置(Dependency Inversion)、契约优先(contract-first)、边界校验与快速失败(fail fast)、幂等性(idempotency)与「至少一次 / 至多一次」语义、事务边界与一致性。骨架一页画出物理分层,本页写的是往各层里加东西时的约束,两处引用同一份描述。
2规范条目
十二条,每条都要落到具体的检查动作上。
| 条目 | 要写清什么,为什么这样规定 | 怎么检查 |
|---|---|---|
| 分层与依赖方向 | 接口层 → 业务层 → 数据访问层,外部能力收在最外侧的适配层(adapter);禁止反向依赖与跨层直连。反向依赖一旦出现,改动任何一层都要通读全部代码 | 新增模块落在规定的层即为通过;业务层出现数据访问语句即判违规 |
| 接口命名与版本控制 | 资源用小写复数、路径带版本前缀;HTTP 方法与语义一致(读 GET,写 POST / PUT / PATCH,删 DELETE);不以动词作路径。版本前缀让新旧契约可以并存一段时间 | 路由清单逐个核对;命名不一致由静态检查发现 |
| 请求与响应结构 | 成功与失败返回同一套外层结构,含业务码、可读信息、数据、请求标识(request ID),全项目只用这一套。调用方据此写一遍解析逻辑,不必按接口分支 | 接口文档与实现比对;新增接口复用同一响应封装 |
| 错误码体系 | 错误码分区(参数 / 认证 / 授权 / 业务 / 依赖不可达),各区对应各自的 HTTP 状态;新增错误码登记进清单。即兴编号会让错误处理退化成字符串比较 | 错误码清单与实际返回值比对;出现清单外的错误码即判缺陷 |
| 参数校验的位置 | 校验在接口层边界完成,业务层只接收已校验的数据;校验失败返回统一错误结构。这是快速失败的具体落法:越早拒绝,代价越低 | 故意把必填校验写进业务层,检查是否被指出 |
| 数据访问与事务 | 查询只出现在数据访问层;事务边界在业务层;结构变更必须条件更新且可回滚。事务跨越多层时,回滚语义就无从说清 | 迁移脚本审查;执行一次回滚验证可逆 |
| 事务内的禁止项 | 事务内只包含必要的数据库读写与一致性校验;不得夹带外部 HTTP 调用、消息投递、文件上传或长耗时计算;涉及外部通知与异步任务时改用 Outbox 或事件表等最终一致性方案,并写明谁写入、谁投递、失败如何重试与补偿。为什么:外部调用不可回滚——事务回滚之后副作用仍留在对端,且长事务会放大锁冲突 | 在事务内注入一次外部调用,检查是否有检查手段能发现;人为回滚一次,核对外部副作用是否残留 |
| 幂等与并发 | 每个写接口声明是否幂等;同一请求重复送达不产生重复副作用,唯一约束落在存储层而不是应用层判断——应用层判断存在「检查」与「写入」之间的时间窗 | 同一写请求连续发送两次,比对结果;并发场景下重复键应被约束拦截 |
| 分页、排序与筛选 | 参数名与默认上限统一;排序与筛选字段走白名单。白名单之外一律拒绝,避免把用户输入直接拼进查询条件 | 传入白名单外的字段应被拒绝;超过默认上限应被截断 |
| 排序的唯一兜底键 | 排序键不唯一时,必须追加一个唯一键(通常取主键)作为兜底排序条件。为什么:排序不稳定时,同一条记录可能同时出现在两页,也可能一页都不出现 | 构造一批排序键相同的记录,翻两页比对记录集合是否重复或缺失 |
| 非法筛选的失败策略 | 筛选条件不合法(字段不存在、取值越界、类型不符)时返回明确错误,不得按「未传条件」处理,更不得返回全量数据。为什么:这是默认拒绝在查询语义上的延伸——退化为全量,等于把一次越权读放大成全表读 | 传入不存在的筛选字段与越界取值,检查是否明确报错;结果条数不应多于合法查询 |
| 配置外置 | 地址、密钥、特性开关只从环境变量读取;代码中不出现字面量,缺失即启动失败。带默认值继续运行会把配置错误推迟到最坏的时刻暴露 | 删除一个环境变量,应用应启动失败而非带默认值运行 |
3本课先写到哪
先写会立刻被触碰的五条,余下的随第一条业务能力的实现再补。
- 最小集合五条。分层与依赖方向、接口命名与版本控制、统一响应结构、错误码清单、配置外置。
- 用两个接口验证。让 Harness 新增一个读接口与一个写接口,检查是否落在指定层、响应是否走同一套结构、错误是否登记。
- 写一次违规验证。故意让业务层直接执行查询,检查是否被指出或拦截;没被拦下说明规则没有被读到。
- 登记幂等声明。每次变更新增的写接口,在规约里写明是否幂等,测试规范据此配重复请求的用例。
最易腐烂的两项是响应结构与错误码——一旦出现第二套写法,后面所有调用方都要分支处理。把它们放在同一份文件里,并规定新增错误码必须登记。