REST一词最早是在2000年,由Roy Fielding在他的博士论文《Architectural Styles and the Design of Network-based Software Architecture》中提出的。他在本文中创造了REST这个术语。这篇论文的地址是:https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm。
REST的全称是 Representational State Transfer(状态表述转换)。这个词表面看起来可能不太好理解。但其实REST就是勾画出了这样一幅景象,它描述了Web应用到底怎么样设计才算是优良的。这里定义了以下三点:
论文中还提到,REST是一种为分布式超媒体系统所用的架构风格,也就是说,REST定义了一种架构风格来帮助创建和组织出更好的分布式系统。这里的关键词是架构风格。
概括的说:
REST背后的主要思想就是:采用RESTful架构风格进行组织的分布式系统,将在以下几个方面得到改善:
从上面这个列表,我们可以看出,一个以组件为中心设计的系统非常容易出错,如果一个组件出现了故障而不影响整个系统的稳定性,那这样对任何系统都是极有好处的。对组件进行互联是非常简单的,但是需要在添加新特性或扩大缩小规模时将风险降至最低。凭借REST的可移植性,使用REST思想进行设计的系统可以为更广泛的受众使用。通过通用的接口,系统可以被更广泛的开发者所使用。为了实现这些属性和好处,REST使用一组约束来帮助定义统一的接口。
为了定义REST架构,首先要定义出一个空无的状态,也就是一个没有任何约束的系统。在这里,组件之间的差异就是个迷,然后我们再一个挨一个的往里面添加约束并保证这些约束可以互不干扰、融洽相处。这些约束都定义了实现REST API的框架应该如何被构建和设计。下面就介绍一些这六个约束:
- 资源的标识:针对RESTful Web API而言,就是指URI,只有得到这个资源标识,才有可能找到该资源并对该资源进行操作。但是从概念上来讲,资源和它的表述是分开的。例如,我们通过一个URI找到了服务端的Company这个资源,但是我们得到的Company这个资源的表述和服务端的Company是不一样的,因为我们得到的是JSON格式(大多数情况)的Company数据。同时还有媒体类型(media type)对其进行描述,例如application/json等。如果请求的是xml格式的数据,那么我们通常会得到xml格式表述的数据。所以同一个资源得到的表述也可能是不同的(例如JSON vs Xml)。
- 通过表述来对资源进行操纵:REST的组件对资源的操作(CRUD)是通过首先获取该资源现有的表述或者目标表述,然后在组件之间完成从现有表述到目标表述的转换。换句话讲,当客户端拥有资源表述的时候(包括可能的元数据),那么它就应该拥有足够的信息来修改或者删除服务器上的资源,前提是客户端需要有这些权限。例如,我从服务器获取到了Company的资源响应(包括元数据)之后,凭借这些信息客户端就应该可以成功的删除或修改这个Company的资源数据了。但这又是怎么实现的呢?如果服务器上的Company API支持对Company进行删除或者修改,那么在我们获取(GET)到这个Company资源的响应后,响应里面应该包含着删除或者修改这个Company资源的URI,通过这些URI客户端就可以完成相应的操作。
- 带有自我描述的信息:由于REST是无状态的(没有会话机制),所以发送REST请求的时候,必须把所有相关的信息随着请求一起发送到服务器端。换句话说,需要通过使用元数据或者其它方式,让REST的请求中包含的数据必须带有“自我描述”性的信息,以便让对方知道如何处理该请求。
- 超媒体作为应用程序状态的引擎(HATEOAS):REST架构风格中,客户端是通过超媒体与服务器端动态提供的一个“应用网络”来进行交互的。这里要求在首次进入REST网络时有第一个链接,还要求客户端必须具备处理超媒体内容的能力。除此之外REST对客户端来说再无其它要求。这是书上给出的解释。举个例子,本文第二段中提到用户通过点击网页中的链接来进行跳转的时候,浏览器的状态就变化了。这些链接就是超文本,而超媒体就是超文本的泛化。针对API来说,它就是程序状态的引擎。换句话说,超媒体会驱动如何消费和使用API,它会告诉API消费者使用这些API能做什么,例如:能删除这个资源吗?能修改资源吗?如何能创建这种资源?从哪能获取这个资源?最终,它还允许自包含文档的API。
这些就是REST的约束,而没有实现这些约束的Web API就不是RESTful API,所以现在见到的很多RESTful API并不是真的RESTful API,但是这也不能说明这些API就不好,只不过针对那些没有实现的约束可能要做出一些权衡取舍,付出一些代价。
这个成熟度模型是由Leonard Richardson所提出的,这个模型是用来评价API的成熟度。它的结果分为0,1,3,4共四个级别。我们一个一个看。
这个GET请求的响应除了包含数据之外,还包含链接(超媒体),这些链接可以驱动应用程序的状态。从软件开发的角度讲,就是引入了可发现性和自包含文档。
根据Roy Fielding博士的描述,达到Level 3也仅仅是RESTful API的一个前提。也就是说只有你的API达到了Level 3水平之后,才可以谈论你的API是不是RESTful API。