基础约定
-
接口路径以
/api
或者/[version]/api
开头 -
接口路径以
/api/aa-bb
的方式命名 -
接口路径使用资源的名词而非动词,动作应该由http method体现
-
接口路径中的资源使用复数而非单数
-
接口设计面向开发接口,而非单纯前端业务
-
数据结构
// 不分页数据 { code: 10001, status: 200, message: "请求成功", data: { id: 1, name: "data 1" } } // 分页数据 { code: 10001, status: 200, message: "请求成功", data: { items:[{ id: 1, name: "data 1" }, { id: 2, name: "data 2" }], total: 2 } } // 其中为了code表示业务编码,status表示http相应状态码,如此设计的原因时部分场景下前后端之间经历了不可用的网关或代理,这种情况下客户可以从status分辨业务方的处理结果,而code是为了帮助工程师定位问题,并不是必须的。
- 请求和响应字段采用
aa_bb_cc
的方式命名 - 时间字段以ISO 8601格式返回
YYYY-MM-DDTHH:MM:SSZ
- 空数组使用
[]
,而非null - http方法
方法 场景 例如 GET 获取数据 获取单个:GET /api/tasks/1
、获取列表:GET/api/tasks
POST 创建数据 创建单个:POST /api/tasks
PATCH 差量修改数据 修改单个:PATCH /api/tasks/1
PUT 全量修改数据 修改单个:PUT /api/tasks/1
DELETE 删除数据 删除单个:DELETE /api/tasks/1
- http状态码
状态码 场景 200 创建成功,通常用在同步操作时 202 创建成功,通常用在异步操作时,表示请求已接受,但是还没有处理完成 400 参数错误,通常用在表单参数错误 401 授权错误,通常用在 Token 缺失或失效,注意 401 会触发前端跳转到登录页 403 操作被拒绝,通常发生在权限不足时,注意此时务必带上详细错误信息 404 没有找到对象,通常发生在使用错误的 id 查询详情 500 服务器错误
创建类接口
-
创建完成后直接返回id
-
关联关系只以id为表示,其他字段不应依赖客户端
// √ { user_id: [1, 2, 3] } // × { username: [xx, xx, xx], user_id: [1, 2, 3], ... }
- 参数错误以数组形式返回,并附带用户友好的提示
{ code: 10002, status: 400, message: "参数错误", data: { error: [{ field: "name", message: "缺失" }] } }
查询类接口
-
排序使用sort和order
例如使用 GET
/api/tasks?sort=created_at&order=descend
表示以创建时间降序查询数据 -
分页使用page和per_page
GET
/api/tasks?page=1&per_page=10
表示每页10条查询第一页的数据 -
普通筛选使用键值对,多列模糊查询使用
keyword
关键词,枚举筛选使用数组合并拼接,区间使用xxx_lt
和xxx_gt
关键词例如 GET
/api/tasks?creator=ming
表示查询所有 ming 用户创建的任务例如 GET
/api/tasks?keyword=ming
表示查询任意列包含 ming 关键词的任务例如 GET
/api/tasks?status=pending,complete
表示查询状态为阻塞和完成的任务例如 GET
/api/tasks?weight_gt=10&weight_lt=20
表示查询权重在 10 和 20 之间的任务例如 GET
/api/tasks?weight_gt=10
表示查询权重大于 10 的任务 -
可枚举字段使用有语义英文而非无语义数字
-
合理自然嵌套结构而不是平铺
删除类接口
-
删除接口应酌情提供批量删除
例如 DELETE
/api/tasks?ids=1,2,3
表示批量删除 id 为 1 或 2 或 3 的任务
图标类接口
- 曲线图、柱状图
{ code: 20000, status: 200, message: "请求成功", data: { x_axis: ['2022.04.20','2022.04.21', '2022.04.22'] series: [{ name: '上海用户', data: [5000,4000,3000], color: '#f5f5f5' // 可选,如果加上的话会使用该色值 }, { name: '成都用户', data: [3000,4000,5000], // 注意,没有数据时候也要使用 0 填充,和 x_axis 一一对应 color: '#f5f5f5' }] } }
- 饼图
{ code: 20000, status: 200, message: "请求成功", data: { series: [{ name: '上线用户', value: 1890, color: '#f5f5f5' // 可选,如果加上的话会使用该色值 }, { name: '下线用户', value: 2000, color: '#f5f5f5' }] } }
文件类接口
- 统一提供单文件上传接口(
/api/files
),支持上传所有类型文件// 请求,注意这里是 FormData { file: File } // 响应 { code: 20000, status: 200, message: "上传成功", data: { id: 'bb313c99', url: '/files/bb313c99.pdf' name: '合同.pdf' // 原文件的名称 } }
- 统一提供多文件上传接口(
/api/multiple-files
),支持上传所有类型文件// 请求,注意这里是 FormData { files: [File, File] } // 响应 { code: 20000, status: 200, message: "上传成功", data: [{ id: 'bb313c99', url: '/files/bb313c99.pdf' name: '合同1.pdf' // 原文件的名称 }, { id: 'bb313c88', url: '/files/bb313c88.pdf' name: '合同2.pdf' // 原文件的名称 }] }
- 文件路径至少补全至根路径
// 正确 { code: 20000, status: 200, message: "请求成功", data: { id: 1, name: 'xx' avatar: '/files/bb313c99.png', } } // 错误 { code: 20000, status: 200, message: "请求成功", data: { id: 1, name: 'xx' avatar: 'bb313c99.png' } }
- 对于使用到文件的接口使用文件 id 或地址而非 FormData
// 正确 { name: '新任务 1', file_id: 'bb313c99', // 或 file_url: '/files/bb313c99.pdf', } // 错误 { name: '新任务 1', file: File }