1. 基础约定
1.1 接口路径以 /api
或 /[version]/api
开头
1.2 接口路径以 api/aa-bb/cc-dd
方式命名
1.3 规范使用 HTTP 方法
方法 | 场景 | 例如 |
---|---|---|
GET | 获取数据 | 获取单个:GET /api/tasks/1、获取列表:GET /api/tasks |
POST | 创建数据 | 创建单个:POST /api/tasks |
PUT | 全量修改数据 | 修改单个:PUT /api/tasks/1 |
DELETE | 删除数据 | 删除单个:DELETE /api/tasks/1 |
其它更多请求方法请查阅 MDN Web Docs
1.4 规范使用 HTTP 状态码
状态码 | 场景 |
---|---|
200 | 创建成功,通常用在同步操作时 |
202 | 创建成功,通常用在异步操作时,表示请求已接受,但是还没有处理完成 |
400 | 参数错误,通常用在表单参数错误 |
401 | 授权错误,通常用在 Token 缺失或失效,注意 401 会触发前端跳转到登录页 |
403 | 操作被拒绝,通常发生在权限不足时,注意此时务必带上详细错误信息 |
404 | 没有找到对象,通常发生在使用错误的 id 查询详情 |
500 | 服务器错误 |
其它更多响应状态码请查阅 MDN Web Docs
1.5 基础外层数据结构
- 不分页数据
{
code: 20000,
status: true,
message: "请求成功",
data: {
id: 1,
name: '任务 1'
}
}
- 分页数据
{
code: 20000,
status: 200,
message: "请求成功",
data: [{
id: 1,
name: '任务 1'
}, {
id: 2,
name: '任务 2'
}],
pagination: {
total: 2,
page: 1,
per_page: 10,
}
}
注意:其中 code
表示业务编码,status
表示 HTTP 响应状态码,如此设计的原因是部分场景下前后端之间存在不可控的网关或代理(比如某些网关有一些流量控制策略会导致直接返回 403 响应状态码,此时客户端无法分辨 403 是网关的还是业务方),类似这类情况下为了能够让客户端正确分辨业务方的真实处理结果则需要在响应体加上 status
,而 code
表示的业务编码是为了帮助工程师更容易定位问题,它并不是必须的,这取决你们团队风格。
尽管在响应体中体现了响应状态码,但这并不代表所有 HTTP 就可以全部返回 200 了,无论如何请在条件允许范围内尽可能使用标准的 HTTP 响应状态码
1.6 请求和响应字段采用 aa_bb_cc
方式命名
// 正确
{
role_ids: [11,12,35],
}
// 错误
{
roleIds: [11, 12, 35],
RoleIds: [11, 12, 35],
ROLE_IDS: [11, 12, 35]
}
1.7 时间字段以 ISO 8601 格式返回 :YYYY-MM-DDTHH:MM:SSZ
1.8 空数组使用 [],而不是 null
// 正确
{
code: 20000,
status: 200,
message: "请求成功",
data: {
id: 1,
role_ids: [],
}
}
// 错误
{
code: 20000,
status: 200,
message: "请求成功",
data: {
id: 1,
role_ids: null
}
}
1.9 前后端传输过程以标准 JSON 格式,避免反复正反序列化
// 正确
{
code: 20000,
status: 200,
message: "请求成功",
data: {
roles: [{
id: 1,
name: '角色 1'
}, {
id: 2,
name: '角色 2'
}]
}
}
// 错误
{
code: 20000,
status: 200,
message: "请求成功",
data: {
roles: '[{"id":1,"name":"角色 1"},{"id":2,"name":"角色 2"}]'
}
}
2. 创建类接口
2.1 创建完成后直接返回 id
{
code: 20000,
status: 200,
message: "创建成功",
data: {
id: 1,
}
}
2.2 关联关系只以 id 为标识,其它字段不应依赖客户端,
以创建用户为例:POST /api/users
// 正确
{
username: 'ming'
password: 'xxxx',
role_ids: [1, 2, 3]
}
// 错误
{
username: 'ming'
password: 'xxxx',
role_ids: [{
id: 1,
name: '角色1'
}, {
id: 2,
name: '角色2'
}, {
id: 3,
name: '角色3'
}]
}
2.3 参数错误以数组形式返回,并附带用户友好的提示
{
code: 40000
status: 400;
message: "参数错误",
data: {
errors: [{
field: 'name',
message: '缺失'
}]
}
}
3. 查询类接口
3.1 排序使用 sorts
例如 GET /api/tasks?sorts=created_at:desc,status:asc
表示以创建时间降序查询数据
3.2 分页使用 page 和 per_page
例如 GET /api/tasks?page=1&per_page=10
表示每页 10 条查询第一页数据
注意:其中 page
从 1 开始,而不是 0,如果没有传递 per_page
和 page
参数表示不分页获取所有数据
3.3 尽可能返回所有关联数据展开详情,便于客户端显示
{
code: 20000,
status: 200,
message: "请求成功",
data: {
id: 1,
username: 'ming'
roles: [{
id: 1,
name: '角色 1'
}, {
id: 2,
name: '角色 2'
}, {
id: 3,
name: '角色 3'
}]
}
}
3.4 可枚举字段使用有语义英文而非无语义数字
// 正确
{
code: 20000,
status: 200,
message: "请求成功",
data: {
id: 1,
name: '任务 1'
status: 'pending' // 'pending' | 'complete' | 'error'
}
}
// 错误
{
code: 20000,
status: 200,
message: "请求成功",
data: {
id: 1,
name: '任务 1'
status: 0
}
}
3.5 合理自然嵌套结构而不是平铺
// 正确
{
code: 20000,
status: 200,
message: "请求成功",
data: {
id: 1,
name: '任务 1'
creator: {
id: 1,
username: '小明'
}
}
}
// 错误
{
code: 20000,
status: 200,
message: "请求成功",
data: {
id: 1,
name: '任务 1'
creator_id: 1,
creator_name: '小明'
}
}
3.6 删除接口应酌情提供批量删除
例如 DELETE /api/tasks/1
表示删除 id 为 1 的任务
例如 DELETE /api/tasks?ids=1,2,3
表示批量删除 id 为 1 或 2 或 3 的任务
注意:如果列表数据量较大或容易沉淀无用数据的应提供批量删除功能,比如任务、文件、日志等
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于