REST 代表的是表现层状态转移(REpresentational State Transfer)它只是一种软件架构风格,是一组架构约束条件和原则,而不是技术框架。REST 规范把所有内容都视为资源,也就是说网络上一切皆资源。REST 架构对资源的操作包括获取、创建、修改和删除,这些操作正好对应 HTTP 协议提供的 GET、POST、PUT 和 DELETE 方法。
1.URI规范
- 资源名使用名词而不是动词,并且用名词复数表示。
- Collection:一堆资源的集合。例如我们系统里有很多用户(User), 这些用户的集合就是 Collection。Collection 的 URI 标识应该是 域名/资源名复数
- Member:单个特定资源。例如系统中特定名字的用户,就是 Collection 里的一个 Member。Member 的 URI 标识应该是 域名/资源名复数/资源名称
- URI 结尾不应包含/。
- URI 中不能出现下划线_,必须用中杠线 -代替
- URI 路径用小写,不要用大写。
- 避免层级过深的 URI。超过 2 层的资源嵌套会很乱,建议将其他资源转化为?参数
/schools/tsinghua/classes/rooma/students/zhang # 不推荐
/students?school=qinghua&class=rooma # 推荐
- 将一个操作变成资源的一个属性,比如想在系统中暂时禁用某个用户,可以这么设计 URI:/users/zhangsan?active=false。
- 将操作当作是一个资源的嵌套资源,比如一个 GitHub 的加星操作:
PUT /gists/:id/star # github star action
DELETE /gists/:id/star # github unstar action
- 如果以上都不能解决问题,有时可以打破这类规范。比如登录操作,登录不属于任何一个资源,URI 可以设计为:/login。
2.统一的返回格式
一般来说,一个系统的 RESTful API 会向外界开放多个资源的接口,每个接口的返回格式要保持一致。另外,每个接口都会返回成功和失败两种消息,这两种消息的格式也要保持一致。不然,客户端代码要适配不同接口的返回格式,每个返回格式又要适配成功和失败两种消息格式,会大大增加用户的学习和使用成本。
3.API 版本管理
API 版本有不同的标识方法,在 RESTful API 开发中,通常将版本标识放在如下 3 个位置:* URL 中,比如/v1/users。
- HTTP Header 中,比如Accept: vnd.example-com.foo+json; version=1.0。
- Form 参数中,比如/users?version=v1。
/v1/users,这样做的好处是很直观,GitHub、Kubernetes、Etcd 等很多优秀的 API 均采用这种方式。对于版本,没有严格的标准,根据项目实际需要选择一种方式即可。
4.API命名
API 通常的命名方式有三种,分别是驼峰命名法 (serverAddress)、蛇形命名法 (server_address) 和脊柱命名法 (server-address)。
驼峰命名法和蛇形命名法都需要切换输入法,会增加操作的复杂性,也容易出错,所以这里建议用脊柱命名法。GitHub API 用的就是脊柱命名法:selected-actions
5.统一分页/过滤/排序/搜索功能
REST 资源的查询接口,通常情况下都需要实现分页、过滤、排序、搜索功能,因为这些功能是每个 REST 资源都能用到的,所以可以实现为一个公共的 API 组件。
- 分页:在列出一个 Collection 下所有的 Member 时,应该提供分页功能,例如/users?offset=0&limit=20(limit,指定返回记录的数量;offset,指定返回记录的开始位置)。引入分页功能可以减少 API 响应的延时,同时可以避免返回太多条目,导致服务器 / 客户端响应特别慢,甚至导致服务器 / 客户端 crash 的情况。
- 过滤:如果用户不需要一个资源的全部状态属性,可以在 URI 参数里指定返回哪些属性,例如/users?fields=email,username,address。
- 排序:用户很多时候会根据创建时间或者其他因素,列出一个 Collection 中前 100 个 Member,这时可以在 URI 参数中指明排序参数,例如/users?sort=age,desc。
- 搜索:当一个资源的 Member 太多时,用户可能想通过搜索,快速找到所需要的 Member,或着想搜下有没有名字为 xxx 的某类资源,这时候就需要提供搜索功能。搜索建议按模糊匹配来搜索。
6.域名
域名应该采用多级域名的方式来设置
比如:xxx01.api.alu4r.com、xxx02.api.alu4r.com