RESTful Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 来抽象全部 Web 系统的服务能力,而不一样的是,SOAP 应用都经过定义本身个性化的接口方法来抽象 Web 服务,这更像咱们常常谈到的 RPC。例如本例中的 getUserList 与 getUserByName 方法。缓存
RESTful Web 服务使用标准的 HTTP 方法优点,从大的方面来说:标准化的 HTTP 操做方法,结合其余的标准化技术,如 URI,HTML,XML 等,将会极大提升系统与系统之间整合的互操做能力。尤为在 Web 应用领域,RESTful Web 服务所表达的这种抽象能力更加贴近 Web 自己的工做方式,也更加天然。安全
同时,使用标准 HTTP 方法实现的 RRESTful Web 服务也带来了 HTTP 方法自己的一些优点:服务器
无状态性(Stateless)网络
HTTP 协议从本质上说是一种无状态的协议,客户端发出的 HTTP 请求之间能够相互隔离,不存在相互的状态依赖。基于 HTTP 的 ROA,以很是天然的方式来实现无状态服务请求处理逻辑。对于分布式的应用而言,任意给定的两个服务请求 Request 1 与 Request 2, 因为它们之间并无相互之间的状态依赖,就不须要对它们进行相互协做处理,其结果是:Request 1 与 Request 2 能够在任何的服务器上执行,这样的应用很容易在服务器端支持负载平衡 (load-balance)。架构
安全操做与幂指相等特性(Safety /Idempotence)less
HTTP 的 GET、HEAD 请求本质上应该是安全的调用,即:GET、HEAD 调用不会有任何的反作用,不会形成服务器端状态的改变。对于服务器来讲,客户端对某一 URI 作 n 次的 GET、HAED 调用,其状态与没有作调用是同样的,不会发生任何的改变。分布式
HTTP 的 PUT、DELTE 调用,具备幂指相等特性 , 即:客户端对某一 URI 作 n 次的 PUT、DELTE 调用,其效果与作一次的调用是同样的。HTTP 的 GET、HEAD 方法也具备幂指相等特性。性能
HTTP 这些标准方法在原则上保证你的分布式系统具备这些特性,以帮助构建更加健壮的分布式系统。spa
为了说明问题,基于上面的在线用户管理系统,咱们给定如下场景:
参考一开始咱们给出的用例图,对于客户端 Client2,咱们只但愿它能以只读的方式访问 User 和 User List 资源,而 Client1 具备访问全部资源的全部权限。
如何作这样的安全控制?
通行的作法是:全部从客户端 Client2 发出的 HTTP 请求都通过代理服务器 (Proxy Server)。代理服务器制定安全策略:全部通过该代理的访问 User 和 User List 资源的请求只具备读取权限,即:容许 GET/HEAD 操做,而像具备写权限的 PUT/DELTE 是不被容许的。
若是对于 REST,咱们看看这样的安全策略是如何部署的。以下图所示:
图 4. REST 与代理服务器 (Proxy Servers)
通常代理服务器的实现根据 (URI, HTTP Method) 两元组来决定 HTTP 请求的安全合法性。
当发现相似于(http://localhost:8182/v1/users/{username},DELETE)这样的请求时,予以拒绝。
对于 SOAP,若是咱们想借助于既有的代理服务器进行安全控制,会比较尴尬,以下图:
图 5. SOAP 与代理服务器 (Proxy Servers)
全部的 SOAP 消息通过代理服务器,只能看到(http://localhost:8182/v1/soap/servlet/messagerouter
, HTTP POST)这样的信息,若是代理服务器想知道当前的 HTTP 请求具体作的是什么,必须对 SOAP 的消息体解码,这样的话,意味着要求第三方的代理服务器须要理解当前的 SOAP 消息语义,而这种 SOAP 应用与代理服务器之间的紧耦合关系是不合理的。
众所周知,对于基于网络的分布式应用,网络传输是一个影响应用性能的重要因素。如何使用缓存来节省网络传输带来的开销,这是每个构建分布式网络应用的开发人员必须考虑的问题。
HTTP 协议带条件的 HTTP GET 请求 (Conditional GET) 被设计用来节省客户端与服务器之间网络传输带来的开销,这也给客户端实现 Cache 机制 ( 包括在客户端与服务器之间的任何代理 ) 提供了可能。HTTP 协议经过 HTTP HEADER 域:If-Modified-Since/Last- Modified,If-None-Match/ETag 实现带条件的 GET 请求。
REST 的应用能够充分地挖掘 HTTP 协议对缓存支持的能力。当客户端第一次发送 HTTP GET 请求给服务器得到内容后,该内容可能被缓存服务器 (Cache Server) 缓存。当下一次客户端请求一样的资源时,缓存能够直接给出响应,而不须要请求远程的服务器得到。而这一切对客户端来讲都是透明的。
图 6. REST 与缓存服务器 (Cache Server)
而对于 SOAP,状况又是怎样的呢?
使用 HTTP 协议的 SOAP,因为其设计原则上并不像 REST 那样强调与 Web 的工做方式相一致,因此,基于 SOAP 应用很难充分发挥 HTTP 自己的缓存能力。
图 7. SOAP 与缓存服务器 (Cache Server)
两个因素决定了基于 SOAP 应用的缓存机制要远比 REST 复杂:
其1、全部通过缓存服务器的 SOAP 消息老是 HTTP POST,缓存服务器若是不解码 SOAP 消息体,无法知道该 HTTP 请求是不是想从服务器得到数据。
其2、SOAP 消息所使用的 URI 老是指向 SOAP 的服务器,如本文例子中的 http://localhost:8182/v1/soap/servlet/messagerouter
,这并无表达真实的资源 URI,其结果是缓存服务器根本不知道那个资源正在被请求,更不用谈进行缓存处理。
在一个纯的 SOAP 应用中,URI 本质上除了用来指示 SOAP 服务器外,自己没有任何意义。与 REST 的不一样的是,没法经过 URI 驱动 SOAP 方法调用。例如在咱们的例子中,当咱们经过
getUserList SOAP 消息得到全部的用户列表后,仍然没法经过既有的信息获得某个具体的用户信息。惟一的方法只有经过 WSDL 的指示,经过调用 getUserByName 得到,getUserList 与 getUserByName 是彼此孤立的。
而对于 REST,状况是彻底不一样的:经过 http://localhost:8182/v1/users
URI 得到用户列表,而后再经过用户列表中所提供的 LINK 属性,例如<link>http://localhost:8182/v1/users/tester</link>
得到 tester 用户的用户信息。这样的工做方式,很是相似于你在浏览器的某个页面上点击某个 hyperlink, 浏览器帮你自动定向到你想访问的页面,并不依赖任何第三方的信息。
典型的基于 SOAP 的 Web 服务以操做为中心,每一个操做接受 XML 文档做为输入,提供 XML 文档做为输出。在本质上讲,它们是 RPC 风格的。而在遵循 REST 原则的 ROA 应用中,服务是以资源为中心的,对每一个资源的操做都是标准化的 HTTP 方法。
本文主要集中在以上的几个方面,对 SOAP 与 REST 进行了对比,能够看到,基于 REST 构建的系统其系统的扩展能力要强于 SOAP,这能够体如今它的统一接口抽象、代理服务器支持、缓存服务器支持等诸多方面。而且,伴随着 Web Site as Web Services 演进的趋势,基于 REST 设计和实现的简单性和强扩展性,有理由相信,REST 将会成为 Web 服务的一个重要架构实践领域。