SOAP 和 REST Web 服务有啥区别? SOAP 可以是 RESTful 的吗?
Posted
技术标签:
【中文标题】SOAP 和 REST Web 服务有啥区别? SOAP 可以是 RESTful 的吗?【英文标题】:What is the difference between SOAP and REST webservices? Can SOAP be RESTful?SOAP 和 REST Web 服务有什么区别? SOAP 可以是 RESTful 的吗? 【发布时间】:2015-08-15 09:16:51 【问题描述】:来自 MSDN 杂志 https://msdn.microsoft.com/en-us/magazine/dd315413.aspx 和 https://msdn.microsoft.com/en-us/magazine/dd942839.aspx 我明白了
当使用 HTTP 向 RESTful 端点请求数据时,使用的 HTTP 动词是 GET。
使用 REST 意味着您可以利用 HTTP 缓存和其他有助于扩展服务的功能,例如条件 GET。其中许多技术不能与 SOAP 一起使用,因为 SOAP 仅通过 HTTP 使用 POST。
来自***页面http://en.wikipedia.org/wiki/Representational_state_transfer
RESTful 系统通常(但并非总是)通过超文本传输协议与 Web 浏览器用于检索网页并将数据发送到远程服务器的相同 HTTP 动词(GET、POST、PUT、DELETE 等)进行通信。[
但是使用 HTTP POST 从资源中获取数据会不会违反 REST 架构? 换句话说,基于 SOAP 的 Web 服务可以是 RESTful 的吗?
RESTful 和基于 SOAP 的 Web 服务之间还有其他区别吗?
【问题讨论】:
This 和this 都是关于该主题的好读物。基本上,SOAP
并不真正 依赖HTTP
,这恰好是它实现的最常见的媒介。因为REST
使用HTTP
动词,所以它需要HTTP
协议。根据定义,SOAP
和REST
是互斥的:REST
使用HTTP
路径和查询来访问对象,SOAP
使用消息。
@EBrown REST 通常使用 http,它不是强制性的。这就是我所相信的。如果我错了,请纠正我。
REST
需要使用HTTP
动词来操作,这将其绑定为HTTP-based
服务。另一方面,RESTful
服务是不同的。这就像说Cat
和Cat-like
动物。是的,这两个术语都有Cat
这个词,但它们指的是不同的东西。
不是根据定义。回想一下SOAP-based
服务通过任何媒体交换消息。这就是HTTP-based SOAP
服务使用POST
请求的原因:它们必须保持通过既定介质。 GET
请求对数据大小有非常严格的上限。 (而且它非常小 - 更大的 SOAP
消息永远无法通过。)您可以使用 HTTP POST
获取数据,但它不是 RESTful
服务,因为 HTTP verb
没有任何意义。 RESTful
服务是 RESTful
因为动词表示动作。
我正在添加一个非常详细的答案。 :)
【参考方案1】:
简介
我将其发布为答案,因为 cmets 还不够。以下是我想为您总结的内容。
首先,我们将从这两个参考开始:
http://spf13.com/post/soap-vs-rest
http://blog.smartbear.com/apis/understanding-soap-and-rest-basics/
最后,我想以下面的话开始这篇文章:
SOAP 和 REST 都旨在解决以下问题:两个不同应用程序、程序或设备如何在它们之间交换和共享数据以可扩展且易于理解的方式相互连接?
RESTful 服务
按设计 RESTful(Re展示性S状态T传输)服务使用HTTP
和HTTP
动词(GET
、POST
、PUT
、DELETE
)来表示意图。这些动词非常清楚向用户表明使用它们时会发生什么。服务器可以使用它们来做出抢先决定。也就是说,它可以在动作准备好之前做出决定。
考虑到这一点,您必须从用户插入服务帐户访问少量数据。哪个更容易,GET endpoint/users/account/id
请求,还是具有 id
正文的 POST endpoint/users/account
请求?根据 REST 的定义,POST
请求违反了 REST 所暗示的基本协议。也就是说:服务器应该在数据到达之前知道用户对它的意图。这是 REST 试图保证的基本原理。
这个事实,不,这个基础,要求允许RESTful 通信在客户端开始发送数据之前表明客户端的意图。这允许服务器在消息到达之前很久就接受和拒绝消息,从而减少处理负载。
REST 的另一个方面(尤其是 Twitter、Facebook 和 Google API):以HTTP
为重点和授权的RESTful 服务可以利用HTTP
响应标头。也就是说,如果不允许客户端访问,他们可能会以HTTP 403 Forbidden
消息进行响应。 基于 SOAP 的服务可能不会。结果消息必须表明这样的结果。
RESTful 服务倾向于将HTTP verbs
(或动作)与名词(或实体/对象)相关联。一般来说,复数和单数更多地暗示了动作。 IE。 GET RootEndpoint/Employees
预计会返回所有 员工(或至少一个符合特定标准的大组)。而GET RootEndpoint/Employee/12
预计会返回一个 员工。 (通常是 ID 为 12 的员工。)
RESTful 服务在HTTP verb
(GET
、POST
、PUT
、DELETE
)和 这就是两者之间联系的目的:没有什么特别的东西需要添加到消息正文中来指示用户打算做什么。(我将继续始终强调这一点。)
REST 完全是为HTTP
设计的。而且它非常擅长它的工作。
RESTful 过滤
一般来说,要过滤REST
服务请求,您需要包含多个 URL 段,每个段指示其后面的参数。
我将从 Spotify API 中举一个例子:https://developer.spotify.com/web-api/get-playlist/
:
获取播放列表
获取 Spotify 用户拥有的播放列表。
端点
GET https://api.spotify.com/v1/users/user_id/playlists/playlist_id
请求参数
+---------------------------------------------------+ | Path parameter | Value | +---------------------------------------------------+ | user_id | The user's Spotify user ID. | | playlist_id | The Spotify ID for the playlist. | +---------------------------------------------------+
在该 API 端点中,您指定要查找具有 user_id
的 user_id
的 users
对象和具有 playlist_id
的 playlists
对象(在该 users
对象内) 987654359@.
一些 RESTful 服务允许参数上的组合标志。
以 Stack Exchange API 为例。您可以通过用分号分隔多个问题或答案来获取多个问题或答案,它基本上会过滤到这些问题或答案。
如果我们分析this endpoint (/questions/ids/answers),你会看到它指定:
获取 id 中标识的一组问题的答案。
如果您有一组有趣的问题,并且希望一次获得他们的所有答案,或者如果您正在轮询新的或更新的答案(与 sort=activity 结合使用),则此方法最有用。
ids
最多可以包含 100 个以分号分隔的 id,要以编程方式查找 id,请在问题对象上查找question_id
。此方法接受的排序对答案对象的以下字段进行操作:
这也是一个很好的 API 示例,它允许额外的 GET
请求进一步过滤/排序结果。
使用示例:https://api.stackexchange.com/2.2/questions/30581530/answers?order=desc&sort=activity&site=***
现在,如果我们对/answers/ids endpoint 做同样的事情,我们可以想出类似的东西:https://api.stackexchange.com/2.2/answers/30582379;30581997;30581789;30581628?order=desc&sort=activity&site=***
。这为我们提取了四个指定的答案。
我们可以结合更多,例如,与 SE API 并包含过滤器来限制返回的字段:https://api.stackexchange.com/2.2/questions/30581530/answers?order=desc&sort=activity&site=***&filter=!)V)P2Uyugvm
。 (有关 filter
参数的说明,请参阅 this link to /2.2/filters。)
基于 SOAP 的服务
输入 SOAP(Simple Object Access Protocol) ,它是 REST 的前身。 SOAP 通过来回发送消息解决了这个问题。他们使用XML
(尽管您可以在没有它的情况下构建基于SOAP的服务,类似于在没有JSON
的情况下构建RESTful服务)来交换消息,因此服务器没有初始指示要做什么。
基于 SOAP 的服务以与传输介质无关的方式解决了这个问题。服务器和客户端根本不需要使用HTTP
,甚至是TCP
。他们只需要使用相同或兼容的传输媒介。事实上,您可以将现代企业环境视为基于 SOAP 的服务。当您需要购买新的用品时,您可以向您的办公室经理提出申请,然后他会回复一条消息。收到初始申请后,您的经理不知道是否允许。他们必须阅读申请的其余部分,以确定它是有效的还是无效的。
SOAP 是围绕RPCs
(远程过程调用)设计的,许多防火墙会阻止这些。因此,SOAP 被修改为在 HTTP
上工作。它旨在集成截然不同的技术。
因为 SOAP 是围绕消息设计的,所以它是一个非常更详细的服务。在SOAP 服务中表示复合动作 通常更容易。也就是说,如果您基于 许多 标准(而不仅仅是一个)请求objects
,SOAP 往往有更好的接口。
基于 SOAP 的过滤
基于 SOAP 的服务过滤器在 RPC 中具有附加字段。这些字段的组合方式取决于提供者。
我将从 Global Weather API 中举一个例子:http://www.webservicex.net/globalweather.asmx?op=GetWeather:
获取天气
获取全球所有主要城市的天气报告。
测试
要使用 HTTP POST 协议测试操作,请单击“调用”按钮。
+---------------------------------------------------+ | Parameter | Value | +---------------------------------------------------+ | CityName: | | | CountryName: | | +---------------------------------------------------+
例如,如果您指定“Blanding”和“United States”,您将看到生成的 XML 如下所示:
<?xml version="1.0" encoding="utf-8"?> <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <GetWeather xmlns="http://www.webserviceX.NET"> <CityName>Blanding</CityName> <CountryName>United States</CountryName> </GetWeather> </soap12:Body> </soap12:Envelope>
这将作为对 http://www.webservicex.net/globalweather.asmx/GetWeather
的基于 POST 的调用提交(对于 HTTP SOAP 请求)。
回到原来的问题:
基于 SOAP 的 Web 服务可以是 RESTful 的吗?
这是您最初的问题,根据我提供的信息,我相信它不能。这两个服务互斥。 REST 打算通过交换表示意图的headers
和表示目的的message bodies
来解决问题。 SOAP 打算通过交换表明意图和目的的messages
来解决问题。
使用 HTTP POST 从资源中获取数据是否违反 REST 架构? 是的。 RESTful 服务架构旨在使用术语POST
来表示特定操作。REST 中的每个HTTP verb
都表示该操作打算做什么。
正如我在最初的问题上所说的那样:
您可以使用
HTTP POST
获取数据,但它不是RESTful 服务,因为HTTP verb
没有任何意义。 RESTful 服务是RESTful,因为动词 表示动作。
我该选择什么,SOAP 还是 REST?
这部分主要面向未来的读者。
这两种协议各有优缺点,应该根据问题的需求来选择使用哪种协议。指导您如何做到这一点超出了本问答的范围。也就是说,需要考虑三件事:了解您的项目,了解您的要求,最重要的是,为您的受众正确记录它。
【讨论】:
就网络服务而言,意图和目的这两个词是什么意思? Intent 描述了您想要完成的工作。 即,当您通过REST 发送HTTP GET
请求时,您表明您的intent 是检索数据。目的描述实际的实现或数据。HTTP GET
的目的是描述我的意图检索数据。我可能需要进行一些编辑以清除它们。
我假设在 GetEmployees/12 请求中,GET 是意图,12 是目的。 PutEmployees/12 或 DeleteEmployees/12 请求怎么样?是 PUT 意图还是 PUT/12 意图和 12 目的细节? GetAllEmployees/ 的目的又如何呢?我假设 DELETE 和 PUT 的行为相同。
@user2330678 在第一种情况下:GET Employee/12
将是最被接受的形式,其意图是GET
一些数据。 目的是GET Employee number 12
. Intent 描述了更广泛的目标。 Purpose 描述了你正在做什么。 REST 中有 4 个意图:GET
、POST
、PUT
和 DELETE
。
@user2330678 也就是说,REST从字面上将复数和单数联系起来。 GET Employees
将返回所有(或许多)Employee
对象。而GET Employee/12
将返回一个Employee
对象。而使用 SOAP 服务,因为它们是基于消息的,它们可以更容易地表示复合动作。 (例如,按多个条件过滤。)【参考方案2】:
从概念上讲,服务非常不同。
SOAP 是关于远程过程调用 (RPC) 的,这意味着它旨在远程调用方法。客户端上的服务器方法代理必须与服务器保持同步。 WSDL 通常用于保持模型同步。
SOAP 也忽略了很多 HTTP 特性。正如您所提到的,它对所有内容都使用 POST 方法。它还以专有的 XML 数据格式包装数据。
REST 使用 URL 来引用资源。资源表示可以是任何格式(json、xml、csv、二进制...),并且可以利用 HTTP 内容协商(Accept* 标头)。 HTTP 方法很好地映射到 CRUD 方法。
真正的 REST 服务必须使用超媒体驱动的数据格式(HAL、JSON 集合……或供应商自定义)。它提供了从单个固定 URL 发现相关资源链接的能力。
http://en.wikipedia.org/wiki/HATEOAS
我看不出相同的服务(单一合同)如何满足所有这些标准。
【讨论】:
【参考方案3】:是的,有区别。
服务中的端点将彼此不同。
您可以毫无问题地为您的 RESTful 服务使用所有 HTTP 动词。
在您的 RESTful 中,您可能想要发送 json 而不是 XML。 看看下面的例子。
<services>
<service name="TestService">
<endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
<endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="ITestService"/>
</service>
</services>
【讨论】:
REST 标准中没有规定使用 JSON、XML、html 等也是可以接受的。是的,大多数 RESTful 服务都使用 JSON,因为它是一个较小的有效负载,因此移动设备可以在有限的带宽上使用它【参考方案4】:REST 使用 HTTP 动词来表达您想要完成的操作。
“GET”请求要求服务在某个位置返回项目。
“POST”请求要求服务在某个位置创建一个新实体(这可能会在幕后持久化到数据库中)。
“PUT”请求要求服务更新某个位置的现有实体。
“DELETE”请求要求服务删除某个位置的现有实体。
所以不,您不能真正将“POST”用于“GET”之类的东西,并且仍然称自己为 REST API。您的消费者会对此感到非常困惑。
【讨论】:
来自 wiki 页面,“RESTful 系统通常但不总是通过超文本传输协议与 Web 浏览器用于检索的相同 HTTP 动词(GET、POST、PUT、DELETE 等)进行通信网页并将数据发送到远程服务器。”那么,是不是所有操作都可以使用 POST 呢? 一切皆有可能,你想怎么写就怎么写。如果您愿意,您可以让“DELETES”创建新记录和“GETS”删除记录。但是你会让你的消费者感到困惑。所以,只要坚持其他人都理解的约定。这就是 REST 流行的原因。这是按惯例理解的。 @user2330678 是的,可以将所有 POST 用于 RESTful 服务(我遇到过一些正是这样做的),它们仍然是 RESTful 服务。但是,除非有很好的理由,否则最好坚持已建立的约定。以上是关于SOAP 和 REST Web 服务有啥区别? SOAP 可以是 RESTful 的吗?的主要内容,如果未能解决你的问题,请参考以下文章