RESTful的理解
REST(Representational State Transfer)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。
概述
REST从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源。获得资源致使应用程序转变了状态。REST定义了一组体系架构原则,可根据这些,包括使用不同语言编写的客户端如何通过HTTP处理和传输资源状态。REST对Web的影响非常大,由于其使用很方便,已经普遍取代了基于SOAP和WSDL的接口设计。
设计原则
- 显式地使用不同的 HTTP 请求方法
- 无状态
- 公开目录结构式的 URI(通过逻辑URI定位资源)。
显式地使用不同的 HTTP 请求方法
我们在 Web 应用中处理来自客户端的请求时,通常只考虑 GET 和 POST 这两种 HTTP 请求方法。实际上,HTTP 还有 HEAD、PUT、DELETE 等请求方法。而在 REST 架构中,用不同的 HTTP 请求方法来处理对资源的 CRUD(创建、读取、更新和删除)操作:
- 若要在服务器上创建资源,应该使用 POST 方法。
- 若要检索某个资源,应该使用 GET 方法。
- 若要更改资源状态或对其进行更新,应该使用 PUT 方法。
- 若要删除某个资源,应该使用 DELETE 方法。
经过这样的一番扩展,我们对一个资源的 CRUD 操作就可以通过同一个 URI 完成了:
(读取)[GET] http://www.example.com/photo/logo
仍然保持为 [GET] http://www.example.com/photo/logo
(创建)http://www.example.com/photo/logo/create
改为 [POST] http://www.example.com/photo/logo
(更新)http://www.example.com/photo/logo/update
改为 [PUT] http://www.example.com/photo/logo
(删除)http://www.example.com/photo/logo/delete
改为 [DELETE] http://www.example.com/photo/logo
从而进一步规范了资源标识的使用。
通过 REST 架构,Web 应用程序可以用一致的接口(URI)暴露资源给外部世界,并对资源提供语义一致的操作服务。这对于以资源为中心的 Web 应用来说非常重要。
无状态
应该注意区别应用的状态和连接协议的状态。REST对于连接的无状态性实际上要求每次经过无状态的连接协议传送的信息必须包含应用中所有的状态信息。
在 REST 的定义中,一个 Web 应用总是使用固定的 URI 向外部世界呈现一个资源。它认为Web是由一系列的抽象资源组成,这些抽象的资源具有不同的具体表现形式。
譬如,定义一个资源为photo,含义是照片,它的表现形式可以是一个图片,也可以是一个.xml的文件,其中包含一些描述该照片的元素,或是一个html文件。 并且这些具体的表现可以分布在不同的物理位置上。
通过逻辑URI定位资源
实现这种级别的可用性的方法之一是定义目录结构式的 URI。此类 URI 具有层次结构,其根为单个路径,从根开始分支的是公开服务的主要方面的子路径。 根据此定义,URI 并不只是斜杠分隔的字符串,而是具有在节点上连接在一起的下级和上级分支的树。例如,在一个收集photo的相册中,您可能定义类似如下的结构化 URI 集合:
http://www.example.com/photo/topics/{topic}
如:http://www.example.com/photo/topics/home
根 / photo之下有一个 /topics 节点。 该节点之下有一系列主题名称,例如生日照片,聚会照片等等,每个主题名称指向某个讨论线。 在此结构中,只需在 {topic}输入某个内容即可容易地收集讨论线程。
在某些情况下,指向资源的路径尤其适合于目录式结构。 例如,以按日期进行组织的资源为例,这种资源非常适合于使用层次结构语法。
此示例非常直观,因为它基于规则:
http://www.example.com/photo/2010/02/22/{topic}
第一个路径片段是四个数字的年份,第二个路径片断是两个数字的月份,第三个片段是两个数字的日期。这就是我们追求的简单级别。 在语法的空隙中填入路径部分就大功告成了,因为存在用于组合 URI 的明确模式:
http://www.example.com/photo/{year}/{day}/{month}/{topic}
从而不需要我们去这样去传递信息:http://www.example.com/photo?year=xxxx&day=xxx$month=xxx&topic=xxxx
优点
- HTTP头中可见的统一接口和资源地址:通过对于HTTP Head 的解析,我们便可以了解到当前所请求的资源和请求的方式。这样做对于一些代理服务器的设置,将带来很高的处理效率。REST 系统中所有的动作和要访问的资源都可以从HTTP和URI中得到,这使得代理服务器、缓存服务器和网关很好地协调工作。而RPC模型的SOAP 要访问的资源仅从 URI无法得知,要调用的方法也无法从HTTP中得知,它们都隐藏在 SOAP 消息中。
同样的,在REST系统中的代理服务器还可以通过 HTTP 的动作 (GET 、 POST)来进行控制。 - 返回一般的XML格式内容:一般情况下,一个RESTful Web Service将比一个传统SOAP RPC Web Service占用更少的传输带宽。
- 安全机制:REST使用了简单有效的安全模型。REST中很容易隐藏某个资源,只需不发布它的URI;而在资源上也很容易使用一些安全策略,比如可以在每个 URI 针对 4个通用接口设置权限;再者,以资源为中心的 Web服务是防火墙友好的,因为 GET的 意思就是GET, PUT 的意思就是PUT,管理员可以通过堵塞非GET请求把资源设置为只读的,而现在的基于RPC 模型的 SOAP 一律工作在 HTTP 的 POST上。而使用 SOAP RPC模型,要访问的对象名称藏在方法的参数中,因此需要创建新的安全模型。
关于RESTful优点,知乎中的一些回答
知乎用户,← 我厂招聘 Web 前后端开发
- 透明性,暴露资源存在。
- 充分利用 HTTP 协议本身语义。
- 无状态,这点非常重要。在调用一个接口(访问、操作资源)的时候,可以不用考虑上下文,不用考虑当前状态,极大的降低了复杂度。
hebby,Yahoo!北京
- 轻量,直接基于http,不在需要任何别的诸如消息协议。get/post/put/delete为CRUD操作
- 面向资源,一目了然,具有自解释性。
- 数据描述简单,一般以xml,json做数据交换。
周宇刚,ThoughtWorker
- 服务自解释
- 降低服务的版本粒度
- 降低消费者对服务内部实现细节的耦合