REST一夜兴起?有些人可以说REST是HTTP出现之日就伴随而生的原则。

但是毋庸置疑的事实是,在Google和Yahoo等网络巨头发布的相同功能的Web Service API中,REST无疑受到更多的青睐。

SOAP (Simple Object Access Protocol) ,是一个严格定义的信息交换协议,用于在WS中把调用的数据封装成机器可读的格式化数据(xml,json等)。

事实上SOAP数据使用XML数据格式,定义了一整套复杂的标签,以描述调用的远程过程、参数、返回值和出错信息等等。

而且随着需要的增长,又不得增加协议以支持安全性,这使SOAP变得异常庞大,背离了简单的初衷。另一方面,各个服务器都可以基于这个协议推出自己的API,即使它们提供的服务及其相似,定义的API也不尽相同,这又导致了WSDL的诞生。

WSDL (Web Service Description Language) 也遵循XML格式,用来描述哪个服务器提供什么服务,怎样找到它,以及该服务使用怎样的接口规范,简言之,服务发现。

现在,使用Web Service的过程变成,获得该服务的WSDL描述,根据WSDL构造一条格式化的SOAP请求发送给服务器,然后接收一条同样SOAP格式的应答,最后根据先前的WSDL解码数据。绝大多数情况下,请求和应答使用HTTP协议传输,那么发送请求就使用HTTP的POST方法。

REST

抛开R. T. Fielding博士论文里晦涩的理论不说,REST应该满足这样的特点:

1)客户端和服务器结构;

2)连接协议具有无状态性;

3)能够利用Cache机制增进性能;

4)层次化的系统;

5)按需代码。

SOAP和REST区别

大多数SOAP是运行在HTTP上,使用URI标识服务(一个服务对应着一个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优点,简单直观,把HTTP协议利用到了极致,甚至HTTP的作者都没想到后期会有怎么紧密结合的应用。

利用了HTTP的消息头来指明消息的表示形式,用HTTP返回错误的status返回服务资源访问错误。

由此带来的直接好处是构建的成本减少了,例如用URI定位每一个资源可以利用通用成熟的技术,而不用再在服务器端开发一套资源访问机制。又如只需简单配置服务器就能规定资源的访问权限,例如通过禁止非GET访问把资源设成只读。
服务器无状态带来了更多额外好处,因为每次请求都包含响应需要的所有信息,所有状态信息都存储在客户端,服务器的内存从庞大的状态信息中解放出来。

而且现在即使一台服务器突然死机对客户的影响也微乎其微,因为另一台服务器可以马上代替它的位置,而不需要考虑恢复状态信息。更多的缓存也变成可能,而之前由于服务器有状态,对同一个URI的请求可能导致完全不同的响应。

总体结果是,网络的容错性和延展性都增强了,这些本来是WEB设计的初衷,日趋复杂和定制的WEB把它们破坏了,现在REST又返璞归真,试图把Web Service带回简单的原则中来。

REST不足,无状态带来的巨大优势,也带来了难以解决的问题。

例如,怎样授权特定用户才能使用的服务?怎样验证用户身份?如果坚持服务器无状态,也就是不记录用户登录状态,势必要求每一次服务请求都包含完整的用户身份和验证信息。在这种情况下,怎样避免冒认?怎样避免用户信息泄漏?事实上,构建REST附属的安全机制已经在讨论中,其结果无非导致另一个SOAP:

复杂的需求摧残了易用性。

REST的支持者声称REST的请求和应答数据简单可读,而SOAP则需要一系列繁琐的封装;

即使如此,SOAP仍然不能达到接口的一致性,不同的厂商有各自的接口,而REST只使用HTTP定义的方法,因此是通用的。事实确实如此吗?

试想用REST实现两数求和的服务,如果按照建议的做法,把服务(此处是加法)作为一个资源,参数(此处是两个加数)作为请求的参数,结果以XML或JSON语法返回,是否比SOAP更简单易用?

通用接口仍然没法达到,因为资源的名称、参数的名称、结果的格式仍然是服务提供者定义的。为了解决这个问题,提出了WASL(Web Application Description Language)来描述REST接口。WADL就像是WSDL的REST版,随着REST被应用到复杂的领域,SOAP的影子无处不在。