文章目录
概述
- REST是一种很笼统的概念。
- RESTful(REST)是一种(软件的)架构风格,这种风格专门用于API设计,让API设计看上去更优雅。
2000年,Roy Thomas Fielding博士在他那篇著名的博士论文《Architectural Styles and the Design of Network-based Software Architectures》中提出了几种软件应用的架构风格,REST作为其中的一种架构风格在这篇论文的第5章中进行了概括性的介绍。
REST是REpresentational State Transfer的缩写,可以翻译成表现状态转换,但多数场合中我们只说REST或者RESTful,Fielding在论文中将REST定位为“分布式超媒体应用(Distributed Hypermedia System)”的架构风格(RESTful这种API的风格是为分布式系统准备的),它在文中提到一个名为“HATEOAS(Hypermedia as the engine of application state)”的概念。
我们利用一个面向最终用户的Web应用来对这个概念进行简单阐述:这里所谓的应用状态(Application State)表示Web应用的客户端的状态,可以理解为会话状态。资源在浏览器中以超媒体(HTML)的形式呈现,通过点击超媒体中的链接可以获取其它相关的资源或者对当前资源进行相应的处理,获取的资源或者针对资源处理的响应同样以超媒体的形式再次呈现在浏览器上,由此可见,超媒体成为了驱动客户端会话状态的转换的引擎。
借助于超媒体这种特殊的资源呈现方式,应用状态的转换体现为浏览器中呈现资源的转换。如果将超媒体进一步抽象成一般意义上的资源呈现(Representation )方式,那么应用状态变成了可被呈现的状态(REpresentational State)。应用状态之间的转换就成了可被呈现的状态装换(REpresentational State Transfer),这就是REST。
版本号
在RESTful API中,API接口应该尽量兼容之前的版本,但是在实际业务开发场景中,可能随着业务需求的不断迭代,现有的API接口无法支持旧版本的适配,此时如果强制升级服务端的API接口将导致客户端旧有功能出现故障。
Web端是部署在服务器,因此它可以很容易为了适配服务端的新的API接口进行版本升级,然而Android、IOS、PC等其它客户端是运行在用户的机器上,因此当前产品很难做到适配新的服务端的API接口,从而出现功能故障,这种情况下,用户必须升级产品到最新的版本才能正常使用 为了解决这个版本不兼容问题,在设计RESTful API的时可以使用版本号:在url中保留版本号并同时兼容多个版本。
【GET】 /v1/users/{user_id} 版本v1的查询用户列表的API接口
【GET】 /v2/users/{user_id} 版本v2的查询用户列表的API接口
我们可以不改变版本v1的查询用户列表的API接口的情况下新增版本v2的查询用户列表的API接口,以满足新的业务需求,此时,客户端的产品的新功能将请求新的服务端的API接口地址。虽然服务端会同时兼容多个版本,但是同时维护太多版本对于服务端而言是个不小的负担,因为服务端要维护多套代码。这种情况下,常见的做法不是维护所有的兼容版本,而是只维护最新的几个兼容版本,例如维护最新的三个兼容版本,在一段时间后(当绝大多数用户升级到较新的版本后)废弃一些使用量较少的服务端API接口的老版本,并要求使用非常旧版本产品的用户强制升级(例如IOS,过一段时间强制升级,否则无法使用)。
“不改变版本v1的查询用户列表的API接口”主要指的是对于客户端的调用者而言它看起来是没有改变,而实际上如果业务变化太大,服务端的开发人员需要对旧版本的API接口使用适配器模式将请求适配到新的API接口上。
资源路径
RESTful API的设计以资源为核心,每一个URI代表一种资源,因此URI不能包含动词,只能是名词(形容词也是可以使用,但是尽量少用)。一般来说,不论资源是单个还是多个,API的名词要以复数进行命名,此外,命名名词的时候要使用小写、数字及下划线来区分多个单词,这样的设计是为了与json对象及属性的命名方案保持一致。
例如,一个查询系统标签的接口可以进行如下设计:
【GET】 /v1/tags/{tag_id}
同时,资源的路径应该从根到子依次如下:
【GET】 /{resources}/{resource_id}/{sub_resources}/{sub_resource_id}/{sub_resource_property}
添加用户的角色的设计:用户是主资源,角色是子资源:
【POST】 /v1/users/{user_id}/roles/{role_id}
密码修改这个接口的命名很难完全使用名词来构建路径,此时可以引入action命名:
【PUT】 /v1/users/{user_id}/password/actions/modify
请求方式
- GET:查询资源
- POST:创建资源
- PUT:更新服务端的资源的全部信息
- PATCH:更新服务端的资源的部分信息
- DELETE:删除服务端的资源
实际,包括BAT的请求方式也没有这么细致(仅仅GET、POST):
- 兼容浏览器(IE10以上浏览器才支持PUT、PATCH、DELETE)
- 不是每个人都能做到那么细致
查询参数
RESTful API接口应该提供参数,过滤返回结果。
offset指定返回记录的开始位置,limit指定返回记