后端开发规范
公开教程 · 无需登录

后端开发规范

后端开发规范管两件事:代码怎么分层,以及对外的契约长什么样。Harness 生成代码的速度很快,约束不明确时,同一个项目里会同时出现两三套接口风格与响应结构;每多一套,调用方就多一处分支判断,而分支判断是后期最难删除的一类代码。

1这一页管什么

分层与契约是本页的核心;授权判定与日志字段不在这里。

  1. 管服务端的结构与契约。分层与依赖方向、接口命名与版本控制、请求与响应结构、错误码体系、校验位置、数据访问与事务边界、幂等与并发、配置的读取方式。
  2. 不交由这一页。谁能访问哪一条资源属安全开发规范;日志字段与指标属部署运维规范;前端如何调用接口属产品设计规范。
  3. 两种落法。本页绝大多数条目是常驻约束,写进规则;「按规范加一个接口」「按规范做一次数据迁移」这类流程写成技能。
对应的课程知识点:软件设计中的信息隐藏与依赖倒置(Dependency Inversion)、契约优先(contract-first)、边界校验与快速失败(fail fast)、幂等性(idempotency)与「至少一次 / 至多一次」语义、事务边界与一致性。骨架一页画出物理分层,本页写的是往各层里加东西时的约束,两处引用同一份描述。

2规范条目

十二条,每条都要落到具体的检查动作上。

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

3本课先写到哪

先写会立刻被触碰的五条,余下的随第一条业务能力的实现再补。

  1. 最小集合五条。分层与依赖方向、接口命名与版本控制、统一响应结构、错误码清单、配置外置。
  2. 用两个接口验证。让 Harness 新增一个读接口与一个写接口,检查是否落在指定层、响应是否走同一套结构、错误是否登记。
  3. 写一次违规验证。故意让业务层直接执行查询,检查是否被指出或拦截;没被拦下说明规则没有被读到。
  4. 登记幂等声明。每次变更新增的写接口,在规约里写明是否幂等,测试规范据此配重复请求的用例。
最易腐烂的两项是响应结构与错误码——一旦出现第二套写法,后面所有调用方都要分支处理。把它们放在同一份文件里,并规定新增错误码必须登记。