赞
踩
原则是规范的基本设计思路, 在规范中无法找到相应的设计细节时,则应该按照设计的初衷,思路或者原则来判断应该如何进行设计
关于接口风格的设计一直争论不休, 请看这里 https://www.zhihu.com/question/28570307
根据接口设计目标的不同, 可以主要分成以下两类:
路径名称不允许使用/结尾(需注意检查/结尾的路径是否是有效的)
理由:搜索引擎优化角度考虑,一个同样的页面不应该有两个地址,会被搜索引擎认为是作弊,搜索引擎对无/的地址支持更加友好
蛇底式命名风格(snake_case)
关于分割 分隔符"-“与”_"的选择:
snake_case: 微信开放平台,腾讯开放平台,开源中国 百度,阿里云 gitee.com
camelCase: 京东,百度,爱奇艺
小写无连字符:百度百科
资源名(resources_name)既为接口名称,名词复数形式(批量获取时语义更加),尽量一个单词(简洁) ;
RestFul风格, 基于资源的设计,HTTP Method作为动词,表示要对资源执行的动作
【GET】 /users/1 # 查看某个用户信息
【POST】 /users # 新建用户信息【非幂等, 多次执行可能会新建多个用户】
【PUT】 /users/1 # 更新用户信息【幂等, 同一请求多次执行结果一定相同】, 局部替换或追加资源的字段, PUT也可以用于新增,但需是由客户端能够确定唯一主键的场景
【PATCH】 /users/1 # 对用户信息执行某一个动作【非幂等, 同一请求多次执行可能获得不同结果】, 例如登录错误计数+1 多次执行资源产生的结果不同
【DELETE】 /users/1 # 删除用户信息
设计理由: PUT用于局部更新并不符合HTTP1.1和RFC5789规范,但依然这样设计,理由如下
GITLAB这样去实现, 虽然它不符合规范, Kuberenetes API则遵循了标准
如果PUT只能用于全部替换, 那这个动词似乎没什么意义,而只是PATCH的一个特例
简单批处理请求 (batch)
同时处理多个资源, 但对每个资源的处理是一致的,比如更新同样的资源
【GET】 /users # 查询用户信息列表
【PUT】 /users/1,2,3 # 更新用户信息【幂等, 同一请求多次执行结果一定相同】, 局部替换资源的字段,
【PATCH】 /users/1,2,3 # 对用户信息执行某一个动作【非幂等, 同一请求多次执行可能获得不同结果】, 例如登录错误计数+1 多次执行资源产生的结果不同
【DELETE】 /users/1,2,3 # 删除用户信息
使用RFC6902 JSON Patch规范完成批量处理请求 https://tools.ietf.org/html/rfc6902
原理:同时处理多个资源,但对每个资源的处理是不一致的,更新不一样的字段,甚至处理的动作也是不一致的
建议将动作封装到body中并组合成一个新的body发送给后端
PATCH JSON Patch规范进行批量操作:
用于首页聚合显示,展板展厅类页面
待研究… 目前建议后端封装专用接口,前端一次请求
禁止使用其它HTTP Method
POST 数据提交(意图修改服务器端的数据)
GET 数据获取
接口名使用动宾结构 通常接口对应一个动作或状态而不是操作一个资源, (例如:健康检查, 日志查看,附件上传)
可考虑名称细节继续规范化
两个资源之间可能存在关系,例如班级的学生,老师的学生,用户的角色
目前在资源从属关系上没有太多的实践经验,建议参考gitlab资源接口设计,gitlab从存在较为复杂的逻辑关系
通常建议:
分页及排序参数
参数规范名 | 参数作用 | 位置 | 默认值 | 备注 |
---|---|---|---|---|
page | 当前页码 | 地址栏 | 1 | |
per_page | 每页条目数 | 地址栏 | 20 | 这个值必须有,用以计算需要返回的总条目数 |
limit | 单次请求总条目数限制 | 地址栏 | 100 | 防止意外查询过量数据, 后台也应做最大值限制 |
sort | 升序或降序 | 地址栏 | desc | 降序通常常用,更关心最近操作的条目 |
order_by | 排序列 | 地址栏 | id | 建议不要乱序或随机, 更关心最近插入的条目 |
理由:
sort与order_by的参考gitlab api设计 order_by后面加上by可以避免与sort之间发生歧义 明确表示是排序字段或者排序列
条目筛选参数(行筛选, 返回满足条件的行)
行筛选的筛选参数名应与资源数据返回中的参数名一致,故建议采用蛇底式(snake_case)命名规范
内容筛选参数(列筛选或关系筛选)
内容筛选性参数均为布尔型,注意遵循2.3.3中对布尔值,未传值和传空值两种特殊情况的处理规范
参数规范名 | 参数作用 | 位置 | 备注 |
---|---|---|---|
simple | 只返回简要信息 | 地址栏 | 参考5.1.1 两分组列筛选设计规范 |
[groupname] | 附加分组列信息 | 地址栏 | 参考5.1.2 多分组列筛选设计规范 |
参数类型 | 取值规范 | 备注 |
---|---|---|
布尔型 | 真: true或1 假: false或0 | 未传值,按假值处理,传空值,按真值处理 |
数组型(GET传参) | 1,2,3 | 可用于多条目修改删除, post传参时按相关content-type格式执行 |
时间日期型(优先) | 11位 GMT/UTC时间戳 | 不带有时区信息,防止在多语言操作系统中造成服务器与客户端理解不一致,防止前端或后端的设计依赖特定的时间格式, 缺点不能飙到1970年前的时间 |
时间日期型(备选) | ISO8601规范 | 需要表达1970年以前的时间时考虑 |
枚举型 | 枚举值或枚举名 | 是不太判断得出哪个优先,可实践后获得结论 |
待补充… |
GET请求不允许携带Body
理由: 不符合HTTP规范,有些代理服务器会直接将GET请求的Body丢弃(这些代理服务器或中间服务器不一定在我们能控制的范围内)
请求接口是应准确携带content-type头部, 用于表征请求的body中的数据类型,后端需要具此来解析对应body中的数据
建议: 请求json格式的接口。建议携带content-type=application/json
其它常用content-type值参考下表
Content-Type:application/json (推荐,JsonBody提交, 尤其是参数复杂时, 可清晰的表达嵌套数据,可能是趋势,案例:京东,csdn,airbnb,bilibili)
|-如果是base64个是的图片, 建议图片编码为字符串之后以json格式返回给前端
Content-Type:application/x-www-form-urlencoded (推荐,普通表单提交, 目前这种方式仍然居多)
Content-Type:multipart/form-data (文件上传时, 用于带有文件上传的表单提交)
Content-Type:application/x-protobuf Google ProtoBuf格式, 在前端使用protobuf格式目前仍存在争议, 但仍然可见使用案例(例如: 知乎前端数据分析接口)
Content-Type:text/plain 普通文本
Content-Type:text/html; charset=utf-8 HTML文件
Content-Type:text/css CSS文件
Content-Type:application/javascript; charset=utf-8 JS文件
Content-Type:image/png PNG图片
Content-Type:image/gif GIF图片
Content-Type:image/x-icon ico图片
Content-Type:image/webp WEBP图片
content-type:image/svg+xml SVG图片
账户授权等敏感数据应存储于Cookie当中, 并设置HTTP-only属性,用以阻止js脚本读取权限,禁止存储于LocalStorage等其它存储技术
理由: 目前只有cookie存储具备安全防御机制,也就是Http-only, 防御可能的跨站请求攻击(风险极大)
响应后content-type必须与响应body的数据类型一致,前端会据此对响应body进行类型转换
例如: json的body如果返回text/plain类型 那么前端接受时将识别body为字符串而不是json对象
常用content-type值参考3.
最合适的Ajax内容编码类型 https://segmentfault.com/a/1190000006871099
建议采用 Link Header机制返回分页元信息, 以此不去破坏返回Body中存储的是资源内容的restful设计思想
https://git.d.com/help/api/README.md#pagination-link-header
错误码为7位数据
0表示正常
理由: 因正常只有一种,而错误有很多种, 0为正常便于程序中用if判断
第1位表示错误来源
2 客户端错误(用户自行解决,或管理员协助通过系统配置解决)
4 客户端错误(需要研发介入,修复需要前端修改代码)
5 服务端错误(临时异常,不需要研发介入,修复不需要修改代码)
6 服务端错误(软件bug)
第2-3位表示服务代码(便于统计)
第4-7位表示具体错误(前端引导提示和后端查询)
{
"meta":{
"code":"10000",
"msg": "ok";
}
"data": {} or [], # 内部格式由具体业务决定
}
多行文本类异常信息(仅开发环境)
有些异常的反馈信息文本有多行,多行文本直接以字符串格式包装进json的话,前端的显示非常的丑陋(出现大量的\r\n)符号,因此建议将多行文本封装为字符串列表,以优化浏览器端显示
...
"data": {
"type":"text",
"ip": "暴异常的结点IP",
"exception": [
"line1",
"line2",
"line3"
];
}
...
异常栈类型异常结构(仅开发环境)
异常栈列表是有序的, 所以后端实现时应注意保序
...
"data": {
"type":"exceptions",
"ip": "暴异常的结点IP",
"exception": {
"exception_name1": "exception_message1",
"exception_name2": "exception_message2",
"exception_nam32": "exception_message3",
}
}
...
栈追踪(stacktrace)类型异常结构(仅开发环境)
...
"data": {
"type":"stacktrace",
"ip": "暴异常的结点IP",
"exception": 待定...
}
...
其它对象类型异常结构(仅开发环境)
...
"data": {
"type":"error",
"ip": "暴异常的结点IP",
"exception": {
自定义Object
}
}
...
错误码: 2000301
参数错误信息反馈在data域, data是一个数组,表示一组参数的错误,field字段值应该与参数名称一致,用于帮助前端实现时定位错误的输入框,message可供前端参考提示,但前端可以选择提示此信息也可以考虑以更人性化的方式给出合适的提示
...
"data": [{
"field":"username",
"message": "用户名不满足安全要求";
},{
"field":"mobile",
"message": "手机号格式不正确";
}]
...
接口返回的列字段中,可以分成两组,一组是简要信息,另外一组是扩展信息,建议使用布尔型参数simple进行列筛选
场景示例: 获取用户列表接口, simple=true时只返回用户信息,simple=false时,返回用户信息及用户所属的资源信息(用户的项目,用户的…)
接口返回的列字段中,会被分为多个分组,为每个列分组其一个有含义的名称,当传参groupname=true或传递空值时 ,则返回,未传参或传递false时,不返回属于此分组的列
例如:
GET users?role=&project=
则返回用户基本信息,用户所属用户组信息,用户拥有项目信息
复杂字段筛选,可能会要求控制粒度到每个字段级别,建议使用GraphQL技术实现
0(200) 通用正常, 如果不知道用什么, 就是用这个
0(201) 创建成功, 可用于Rest接口的POST新增对象
0(202) 可用于异步请求, 长任务, 利于短信, 邮件发送, 提示浏览器可以不必保持连接
0(204) 服务器成功响应,但是没有返回数据回, 通常可用于Rest接口的Delete功能
第1位表示错误来源(放置于第一位, 便于程序判断和统计分类) |-2 客户端错误(用户自行解决,或管理员协助通过系统配置解决) |-4 客户端错误(需要研发介入,修复需要前端修改代码) |-5 服务端错误(临时异常,不需要研发介入,修复不需要修改底阿妈) |-6 服务端错误(软件bug) 第2-3位表示服务代码 |-00 系统错误(一般为后端bug或故障导致,或多个服务通用的错误) |-400xxxx 客户端错误(返回结构中给出错误细节) |-4000xxx(4xx) HTTP客户端标准错误映射(一般未请求格式错误,需研发介入修正) |-4000400(400) 其它未细分的请求格式不正确(需研发介入修正) |-4000404(404) 请求资源【接口】不存在(通常需要研发或运维介入修正, 注意与数据不存在区分) |-4000405(405) 不支持的http-method(method错误一定是研发疏忽,需要研发介入修正) |-4000415(415) 不支持的Content-Type(需要介入修正) |-4000601(400) Json语法不正确(需前端研发接入修正) |-200xxxx 用户可自行修正的系统公共错误(考虑前端处理便利, 根据所需处理进行细分,可能存在不同逻辑用返回值区分,相同逻辑不同提示用错误细节区分) |-20001xx(401) 认证类问题(表达用户提供的身份信息的异常) |-2000100(401) 其它位置的认证类问题 |-2000101(401) 需要认证类接口但未提供任何认证信息, 但不确定登录后是否有接口权限或数据权限,前端应根据情况适当进行登录引导 |-2000102(401) 认证信息已失效(例如Token) |-2000103(401) 认证信息不可用(例如Token) |-20002xx(200) 鉴权类问题(表达用户提供合理身份信息后对接口和数据的所有权限异常) |-2000201(200) 请求的【数据】无权限访问,但接口有权限,无法通过登录来解决问题,用户只能放弃访问,或联系管理员授权 |-2000202(200) 请求的【接口】无权限访问,通常无权限的接口不应引导调用,但也可能引导用户申请权限 |-20003xx 请求数据的格式类问题 |-2000301(200) 其它非细分的请求格式或参数不正确 |-2000304(200) 请求的【数据】不存在,注意与接口不存在相区分,接口不存在需要研发介入,数据不存在用户可自行修正 |-500xxxx 服务端错误(返回结构中开发环境给出细节,生产环境之给响应值,不给细节) |-50001xx(503) 数据库相关网络异常 |-5000100(503) 数据库连接异常(配置错误,网络异常等) |-5000101(503) 数据库连接异常(数据库被正常关闭) |-5000102(503) 数据库连接异常(数据库异常退出) |-5000200(503) 负载均衡结点(无可用结点,结点配置错误或网络连接异常) |-50005xx(503) 服务端HTTP网络异常(临时网络故障[可能自动修复], 配置错误[不可自动修复]) |-5000502(503) HTTP协议网络连接异常 对应HTTP502 |-5000503(503) HTTP协议网络连接异常 对应HTTP503 与之上的区别是tcp可以是否可以连通 |-5000504(503) HTTP协议网络连接异常 对应HTTP504 (连接超时) |-600xxxx(500) 初步识别的软件bug(需程序员介入处理) |-6000000(500) 服务端未知错误(软件中未识别和处理的软件bug) |-6000001(500) 空指针异常 |-60001xx(500) 数据库相关错误(未判断出来的) |-6000101(500) SQL语法错误 |-6000102(500) 数据库返回值不符合预期(SelectOne时返回多条记录) |-01 用户权限系统(非通用部分) |-02 文件管理/上传下载系统 |-xx 其它服务代码(一般为用户参数输入错误,业务系统建议使用30以上代码) 第4-7位表示具体错误 |-xx 具体的错误代码(由具体服务定义)
错误码设计 https://blog.csdn.net/yzzst/article/details/54799971
聊聊RESTful https://howardwchen.com/2017/09/18/talk-about-restful-popular-api-design-1/
Kubernetes API规约 https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#patch-operations
【主要参考】Restful风格的接口设计 https://juejin.im/entry/59b8d34c6fb9a00a4455dd04
腾讯开放平台 http://open.qq.com/
URI设计原则 https://stackoverflow.com/questions/1619152/how-to-create-rest-urls-without-verbs/1619677#1619677
Gitlab API V3 https://link.zhihu.com/?target=https%3A//developer.github.com/v3/
返回值的处理 https://www.v2ex.com/t/340607?p=2
RESTful API定义及使用规范 https://zhuanlan.zhihu.com/p/31298060
HTTP状态值https://zhuanlan.zhihu.com/p/31298060
http://wiki.open.qq.com/wiki/v3/user/get_info open.weibo.com
http://wiki.open.qq.com/wiki/website/%E5%BE%AE%E5%8D%9A%E7%A7%81%E6%9C%89%E8%BF%94%E5%9B%9E%E7%A0%81%E8%AF%B4%E6%98%8E
https://docs.open.alipay.com/common/105806
http://open.weibo.com/wiki/Error_code
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318634&token=&lang=zh_CN
http://lbs.amap.com/api/webservice/info/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。