前后端对接规范
什么是规范
约定俗成的标准
目的:
- 提高了开发效率,降低了沟通成本,减少不必要的扯皮;
- 缩短联调时间,减少联调阶段的代码调整,保证开发效率;
- 减少测试阶段排查问题的归属,加快测试进度,保证质量;
- 易于故障排除和在线修复。
协作流程规范:
- 需求确认。对于产品提出需求,涉及的各方包括产品、前端、后端、测试和UED。就需求的认知达成一致是开发的第一步。
- 接口设计。前后端对接接口:后端提供接口,前后端在接口的设计上要达成一个大方向。
正常前端后端都可以来设计接口,我们公司当前后端设计接口,但是前端需要知道知道什么接口 - 技术方案评审:开发前进行技术方案评审,确保各方对需求有统一认识,双方重新确认接口领域的可行性。
- 并行开发,前后端自测:前后端并行开发。在这个阶段,前端可以模拟数据进行页面渲染。
- 开发环境联调:前后端自测完成后,在开发环境上完成接口联调。
流程图:
版本
应该将API的版本号放入URL。
https://api.example.com/v1/
路径
在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的"集合"(collection),所以API中的名词也应该使用复数。
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
HTTP动词
对于资源的具体操作类型,由HTTP动词表示。
常用的HTTP动词有下面五个(括号里是对应的SQL命令)。
GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
DELETE(DELETE):从服务器删除资源。
举行个粟子
GET /zoos:列出所有动物园
POST /zoos:新建一个动物园
GET /zoos/ID:获取某个指定动物园的信息
PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID:删除某个动物园
GET /zoos/ID/animals:列出某个指定动物园的所有动物
DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
过滤
如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果
?limit=10:指定返回记录的数量
?offset=10:指定返回记录的开始位置。
?page=2&per_page=100:指定第几页,以及每页的记录数。
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
?animal_type_id=1:指定筛选条件
返回结果数据
针对不同操作,服务器向用户返回的结果应该符合以下规范。
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
分页
返回资源集合是,包含与分页有关的数据如下
{
"page": 1, # 当前是第几页
"pages": 3, # 总共多少页
"page_size": 10, # 每页多少数据
"has_next": true, # 是否有下一页数据
"has_prev": false, # 是否有前一页数据
"total": 27 # 总共多少数据
}
接口返回的数据结构和状态码
data:业务数据
code:状态码
msg:状态信息。这里是给用户提示的信息。如果需要增加详细错误信息。把msg拆成一个对象{}
{
"code": ok,
"data":[],
"message": {
"text": "参数错误",
"parameters": {
"email": "电子邮件格式不正确"
}
}
}
提供一套统一的错误码规范, 协助多方人员来排查出接口的错误
用户发现错误, 可以截错误码的图, 就能够提供有效的信息帮助开发人员排查错误
测试人员发现错误, 可以通过错误码, 快速定位是前端的问题还是后端接口的问题
发送 HTTP 请求
┌───────────┴───────────┐
发送成功¹ 发送失败²
│ │
┌──────────┴──────────┐ A 例如: A100
获得 HTTP 响应 无法获得 HTTP 响应³
│ │
HTTP status A 例如: A200
┌──────────┴──────────┐
HTTP 成功(200-300) HTTP 异常
│ |
{data, status, statusInfo} H${HTTP status} 例如: H404
┌───────────┴───────────┐
接口调用成功(status:0) 接口调用失败
┌────────┴────────┐ |
客户端处理出错 客户端处理正常 B${status}${statusInfo.message} 例如: B100
|
C 例如: C100
接口传参注意事项:
- 接口实现的大方向遵循 RESTful 风格
- 接口返回的数据结构统一,业务数据,状态码,状态信息
- 统一错误提示
- 前后端数据列表相关接口,如果返回为空则返回空数组
[]
或空集合{}
,减少前端很多琐碎的空值判断,特殊情况的特殊分析 - 调用接口业务失败的常用错误码,未授权,未登录等
- 图片是否全路径,哪端都合适
- 时间字段建议同时返回时间戳的原始值(或 ISO 标准格式)和用于统一显示的格式化文本
- 例如:
{"createTime": 1543195480357, "createTimeText": "2018年11月26日"}
- 例如:
- 大数字返回给前端用字符串类型,防止js溢出
- 逻辑复杂的判断放到后端处理,前端尽量减少现场判断。IF条件多于2个则视为逻辑复杂。
- 后端做好数据整合,避免前端数据重组,树的数据不大,全量返回,数据量大则异步返回
- 不同设备端的接口分开,不共用接口
- 计算型的数据,前端展示实时计算。后端入库后端自行计算
- 接口只展示页面需要用到的字段,不展示多余无用字段
- 控制前端显示逻辑判断放在后端处理,前端尽量减少现场判断。按钮是否展示或禁用通过两个及以上状态判断的,需要后台返回一个新的状态值,只能通过一个状态判断
- 渲染逻辑禁止跨多个接口调用;
以免出现前后端分离之后最容易出现的扯皮现象. 特别是当你碰到做事不主动(无责任感)的后端, 什么都要前端来催. 比如什么接口又缺了一个字段没有提供啦, 什么又少了一个接口啦, 等等诸如此类. 后端不去熟悉业务, 也不看界面原型和需求, 只管把接口做完, 任务完成就万事大吉了, 每天除了等前端通知哪里要修改, 自己就像没事人一样.