转载于:数据库
REST彷佛在一晚上间兴起了,这可能引发一些争议,反对者能够说REST是WEB诞生之始甚而是HTTP出现之日就相伴而生的原则。可是毋庸置疑的事实是,在Google和Yahoo等网络巨头发布的相同功能的Web Service API中,REST无疑受到更多的青睐,所以是否是能够这样说:RPC在一晚上之间衰落了?
在一篇做业的小文章里讨论整套RPC的原理,无疑太过庞大了,何况RPC在Web Service领域的应用也无过XML-RPC以及由此延伸的SOAP而已。在原理上惟一重要的,是传统程序的函数调用和返回在RPC中被请求和应答代替了而已。既然如此,在讨论REST以前先阐述SOAP,多是合乎逻辑的顺序。
什么是SOAP?
SOAP (Simple Object Access Protocol) 顾名思义,是一个严格定义的信息交换协议,用于在Web Service中把远程调用和返回封装成机器可读的格式化数据。事实上SOAP数据使用XML数据格式,定义了一整套复杂的标签,以描述调用的远程过程、参数、返回值和出错信息等等。并且随着须要的增加,又不得增长协议以支持安全性,这使SOAP变得异常庞大,背离了简单的初衷。另外一方面,各个服务器均可以基于这个协议推出本身的API,即便它们提供的服务及其类似,定义的API也不尽相同,这又致使了WSDL的诞生。WSDL (Web Service Description Language) 也遵循XML格式,用来描述哪一个服务器提供什么服务,怎样找到它,以及该服务使用怎样的接口规范,简言之,服务发现。如今,使用Web Service的过程变成,得到该服务的WSDL描述,根据WSDL构造一条格式化的SOAP请求发送给服务器,而后接收一条一样SOAP格式的应答,最后根据先前的WSDL解码数据。绝大多数状况下,请求和应答使用HTTP协议传输,那么发送请求就使用HTTP的POST方法。
什么是REST?
REST (REpresentational State Transfort) 形式上应该表述为客户端经过申请资源来实现状态的转换,在这个角度系统能够当作一台虚拟的状态机。抛开R. T. Fielding博士论文里晦涩的理论不说,REST应该知足这样的特色:1)客户端和服务器结构;2)链接协议具备无状态性;3)可以利用Cache机制增进性能;4)层次化的系统;5)按需代码。说到底,REST只是一种架构风格,而不是协议或标准。但这种新的风格(也许已经历史悠久?)对现有的以SOAP为表明的Web Service形成的冲击也是革命性的,由于它面向资源,甚至连服务也抽象成资源,由于它和HTTP紧密结合,由于它服务器无状态。
REST与SOAP的区别
由于SOAP并不假定传输数据的下层协议,所以必须设计为能在各类协议上运行。即便绝大多数SOAP是运行在HTTP上,使用URI标识服务,SOAP也仅仅使用POST方法发送请求,用一个惟一的URI标识服务的入口。举一个图书馆在线查询管理系统为例,服务提供者必须为每一本书提供一个内部标识,而后可能定义一个listBooks操做来返回一系列图书,一个getBook操做来返回指定的图书,一个createBook操做来向数据库加入新增的图书,一个deleteBook操做来删除做废的图书,每一个操做都有各自的参数,尤为是用内部标识来标识操做的图书。这种设计被诟病之处,在于deleteBook操做也要用POST方法来发送,而其实HTTP协议有更和逻辑的DELETE方法可用。REST正是这样设计的,REST为每个资源(此处是图书)指定一个惟一的URI,而用HTTP的4种方法GET、POST、PUT、DELETE直观地表示获取、建立、更新和删除图书。同时图书集合也是和单本的图书不一样的资源,若是用/books来表明图书列表,/books/ID来表明标识为ID的图书,那么对/books的GET操做就表明返回整个图书列表,对/books/ID的DELETE操做表明删除指定的图书,等等。
REST的优势
REST简单而直观,把HTTP协议利用到了极限,在这种思想指导下,它甚至用HTTP请求的头信息来指明资源的表示形式(若是一个资源有多种形式的话,例如人类友善的页面仍是机器可读的数据?),用HTTP的错误机制来返回访问资源的错误。由此带来的直接好处是构建的成本减小了,例如用URI定位每个资源能够利用通用成熟的技术,而不用再在服务器端开发一套资源访问机制。又如只需简单配置服务器就能规定资源的访问权限,例如经过禁止非GET访问把资源设成只读。
服务器无状态带来了更多额外好处,由于每次请求都包含响应须要的全部信息,全部状态信息都存储在客户端,服务器的内存从庞大的状态信息中解放出来。并且如今即便一台服务器忽然死机对客户的影响也微乎其微,由于另外一台服务器能够立刻代替它的位置,而不须要考虑恢复状态信息。更多的缓存也变成可能,而以前因为服务器有状态,对同一个URI的请求可能致使彻底不一样的响应。整体结果是,网络的容错性和延展性都加强了,这些原本是WEB设计的初衷,日趋复杂和定制的WEB把它们破坏了,如今REST又返璞归真,试图把Web Service带回简单的原则中来。
REST是万能的吗?
可是REST就是万能的吗?无状态带来了巨大的优点,同时也带来了难以解决的问题,例如,怎样受权特定用户才能使用的服务?怎样验证用户身份?若是坚持服务器无状态,也就是不记录用户登陆状态,势必要求每一次服务请求都包含完整的用户身份和验证信息。在这种状况下,怎样避免冒认?怎样避免用户信息泄漏?事实上,构建REST附属的安全机制已经在讨论中,其结果无非致使另外一个SOAP:复杂的需求摧残了易用性。
REST的支持者声称REST的请求和应答数据简单可读,而SOAP则须要一系列繁琐的封装;即便如此,SOAP仍然不能达到接口的一致性,不一样的厂商有各自的接口,而REST只使用HTTP定义的方法,所以是通用的。事实确实如此吗?试想用REST实现两数求和的服务,若是按照建议的作法,把服务(此处是加法)做为一个资源,参数(此处是两个加数)做为请求的参数,结果以XML或JSON语法返回,是否比SOAP更简单易用?通用接口仍然无法达到,由于资源的名称、参数的名称、结果的格式仍然是服务提供者定义的。为了解决这个问题,提出了WASL(Web Application Description Language)来描述REST接口。WADL就像是WSDL的REST版,随着REST被应用到复杂的领域,SOAP的影子无处不在。
面向资源和面向事务
REST在面向资源的应用中左右逢源,但在面向事务的应用中却未如人意。面向资源的应用操做简单,无非建立、读取、改变、删除几项,可是面向事务的应用不容许用户直接操做资源,用户只需向系统提交一个事务说明要求,而后等待事务的完成,就如一个网上银行的用户不直接修改帐户和存款,而是提交一个事务告诉银行本身要转帐。若是把这样的服务当作一种资源,经过向资源发送POST请求完成事务,那不过是SOAP的翻版而已,不管是这样,仍是经过PUT来建立事务,都改变了系统的状态(资源自己未改变,此处是改变了用户的余额),显然违背了REST直观的初衷。
事实上,一些Web Service提供者提供的REST API只有REST的外壳,传输的请求和应答全然是简化了的SOAP,这种新瓶装旧酒的作法只是加深了标准的分歧而已。归根结底REST没法简单地解决一些应用,所以咱们只能看到SOAP在REST外壳下的借尸还魂。没有一项技术能一劳永逸地解决全部问题,只须要在预约的约束下优美地解决所在领域的问题就足够了。一项新技术推出的时候老是引来无数的跟风和吹捧,只有当尘埃落定以后才能获得中肯的评价。缓存