SOAP vs. REST

译文,译自《软件构架实践(第3版 影印版)》。UPDATED: 2014-11-17

如果想让基于Web的应用进行互操作,目前有两种现成的技术可以选择:(1)WS*和SOAP(曾经代表“简单对象访问协议”,但这个缩写现在已经不再适用了)以及(2)REST(代表“表述性状态转移”,有时也写做ReST)。我们怎么看待这两种技术?每种技术都擅长什么?在使用的过程中有什么需要注意的地方?比较这两种技术似乎有点风马牛不相及,但我还是尝试着勾勒一下概貌。

SOAP是基于XML信息的一种协议规范,分布式应用可以通过它交换信息从而进行互操作。通常,SOAP有一组相对应的SOAP中间件互操作标准,以及兼容实现,(合在一起)叫做WS*。SOAP和WS*共同定义了许多标准,如下所示:

  • 服务组成的基础架构。开发者在SOAP中可以使用业务流程执行语言(BPEL)表示业务流程,这些都可以通过WS*服务来实现。
  • 事务。为了确保正确地管理事务,定义了几种Web服务的标准:WS-AT,WS-BA,WS-CAF和WS-Transaction。
  • 服务发现。通用服务发现和集成协议(UDDI)可以让企业发布服务列表并互相发现。
  • 可靠性。SOAP本身并不保证消息的可靠送达。需要可靠性保证的应用必须使用符合SOAP可靠性标准即WS-Reliability的服务。

SOAP非常通用,在远程过程调用(RPC)模型中应用很广,当然在其他模型中也可以使用。SOAP和主流编程语言相比,本身是一个简单类型系统。SOAP使用HTTP和RPC做消息传输,但其实从理论上来说,它可以在任何通信协议上实现。SOAP并不要求服务的方法命名、寻址模型或者过程规范。因此,选择SOAP并没有给应用之间的互操作带来太多的实际帮助——它只是一种信息交换标准。交互的双方要对如何解析负荷(payload)达成共识,只有这样才能获得语义互操作性。

另一方面,REST是基于客户端-服务器的架构风格,它是由一组CRUD(创建、读取、更新、删除)的操作(在REST的世界里,分别是POST,GET,PUT和DELETE)构成,并且只使用一种寻址方式(基于URI,或统一资源标识符)。REST在架构上加入了一些限制:SOAP提供了完整性;REST则提供了简单性。

REST是有关状态和状态转移的,它把Web(以及面向服务的系统能够组合在一起的服务)看作是一个巨大的信息网络,这些信息通过URI寻址的方式进行访问。所以,REST里没有类型的概念,当然也没有类型检查——完全取决于应用来确保交互语义的正确性。

因为REST接口如此简单并且具有一般性,任何HTTP客户端不需要额外的配置,都可以使用REST操作(POST, GET, PUT, DELETE)和任何HTTP服务器通信。这样你就获得了语法上的互操作能力,但是,这些程序实际上做什么以及交换什么信息都需要在组织层面上达成共识。也就是说,服务之间的语义互操作性只有REST接口是保证不了的。

REST基于HTTP,本身设计成自描述形式,在最好的情况下是无状态协议。下面考虑REST的一个例子,一个电话本服务,给定一个唯一标识符,可以查阅某个人:

1
http://www.XYZdirectory.com/phonebook/UserInfo/99999

同样的一个查询,如果用SOAP来实现,可能会是这样:

1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>
<soap:Envelope xmlns:soap=http://www.w3.org/2001/12/soap-envelope
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body pb="http:///www.XYZdirectory.com/phonebook">
<pb:GetUserInfo>
<pb:UserIdentifier>99999</pb:UserIdentifier>
</pb:GetUserInfo>
</soap:Body>
<soap:Envelope>

选择SOAP还是REST的一个方面是你是否能接受SOAP+WSDL(Web服务描述语言)的复杂性和限制,从而得到更多的标准化互操作,或者使用REST从而避免额外的成本,标准更少但是也能获益。还有什么其他点需要考虑呢?

REST中的消息交换比SOAP中的消息交换携带更少的特征。所以在REST和SOAP之间的权衡之一便是各自的消息大小。对于需要交换大量消息的系统,另一个权衡点是性能(倾向于REST)还是结构化信息(倾向于SOAP)。

实现WS*或REST的决定取决于诸如需要的服务质量——WS*的实现对于安全、可用性等有更好的支持——以及功能类型等很多方面。RESTful的实现,由于其简单性,更加适合只读操作,典型是混搭(mashups)型的应用,而这些情境对于服务质量有最小的需求和担心。

好了,如果现在构建一个基于服务的系统,你会怎么选择?真实情况是,在整个过程中你不必只做一个选择;每种技术都相对易用,至少对于简单的应用来说。每种技术都有优势和弱势。就像在架构中的任何其他技术一样,最终都是权衡;你的决定很大程度上取决于在你的环境中那些权衡点如何影响你的系统。

——Rick Kazman

学习REST的参考资料