在解释Web服务或(Web)API之间的差异时,似乎一致认为REST会导致耦合较少的体系结构。
例如:
https://tools.ietf.org/html/draft-li-sdnrg-design-restapi-02提到REST适用于低耦合系统。
https://www.upwork.com/hiring/development/soap-vs-rest-comparing-two-apis/表示SOAP过于高度耦合
考虑减少或轻微耦合的理由是什么?
答案 0 :(得分:1)
在客户端未与特定服务API耦合的系统中,客户端通常具有更强的容错能力,因此除了可用于多个RESTful API之外,还具有强大的功能。它们将适应服务器端所做的更改,而紧密耦合的客户端将无法处理进一步的请求。
在REST API must be hypertext-driven中,Fielding解释了RESTful架构所具有的一些约束,以及如果API不遵守这些规则会发生什么。
当客户端使用链接与某个远程服务器进行交互时,客户端必须知道链接是什么以及它可以对其执行的操作。这些知识通常由HTTP(或任何其他传输协议)和URI规范定义,这些规范通常依赖于某些框架或中间件而构建在客户端中。由于链接是REST的主要部分,客户必须以某种方式学习各自的端点.Fielding在他的博客文章中提到:
...允许服务器通过在媒体类型和链接关系中定义这些指令来指示客户端如何构造适当的URI,例如在HTML表单和URI模板中完成的。
虽然你看到很多所谓的" REST"通过不返回URI或不保留关系中的语义但将它们放入URI中而不支持客户端的服务。即你经常会看到像http://some.server.com/api/v1/users/1234
之类的URI这样的东西可能会让人们知道它的目的,但如果这个"知识"移植到客户端,如果服务器决定(或由某人指示)更改结构中的任何内容,它可能会轻易制动它。如果服务器现在将资源移动到http://some.server.com/api/v1/employees/1234
,则客户端将无法再检索用户/员工的数据,从而中断。
相反,服务器应该向客户端指示所需的信息。它可以添加一些重定向逻辑,在调用前一个URI时通知客户端现在可以在新位置找到该资源。来自服务器本身的响应应该命名这样的URI,以便客户端可以通过名称引用资源端点而不是分析URI。在HTML中,这可以像这样实现:<a href="http://some.server.com/api/v1/employees/1234" rel="user">Sam Sample</a>
。而不是客户端分析语义结构的URI(通常也会导致typed resources),它只是使用服务器给出的内容,并通过样本中的关系名称user
来理解URI的意义。
由于HTTP(或任何其他使用的传输协议)允许在客户端和服务器之间发送几乎任何数据,服务器和客户端使用媒体类型以便就双方能够理解和知道的数据表示格式达成一致处理。因此,媒体类型是某种数据知识的某种知识库。它可以描述文档的语法结构,期望的必要元素以及每个字段的语义。
根据菲尔丁的说法
REST API应该花费几乎所有的描述性工作来定义用于表示资源和驱动应用程序状态的媒体类型,或者为现有标准媒体定义扩展关系名称和/或启用超文本的标记类型。用于描述在感兴趣的URI上使用哪些方法的任何努力都应该在媒体类型的处理规则的范围内完全定义
但是,如果您在StackOverflow中仔细查看大量问题,则大多数消息都以普通JSON进行交换,这些消息不会传达有关接收的实际数据的任何语义,也不会暗示客户端可能执行的操作关于这个数据。 HAL和类似的媒体类型至少提供了一些客户可以用来处理进一步行动的资源和链接的线索。
由于媒体类型定义了关于如何处理某些数据的客户端或服务器,因此它可能包含一个指示,即具有user
之类关系名称的链接引用用户资源,可以从中检索用户资源的更多数据。 。如果资源的URI发生了更改,RESTful客户端仍然可以处理其任务,因为它可以从媒体类型中扣除可以通过关系名称user
检索用户的用户信息。此URI实际上指向的是非常相关的,因为客户端只会调用它来从中检索更多数据。
由于问题也针对SOAP,因此了解SOAP API本质上与REST非常不同非常重要。紧耦合是通过WSDL契约定义的,该契约定义了服务器端点以及可调用的操作以及所需的参数和响应类型。如果服务器在客户端实现该合同之后添加或(重新)移动某些参数,则客户端将无法发送进一步的请求,因此需要在其继续工作之前进行更新。
在这个让服务器围绕某些资源移动的非常简单的情况下,希望很明显客户的知识保存在媒体类型中,并且它通过与服务交互而不是在服务中实现它的状态。代码本身(如SOAP或任何专有的Web-API客户端)。因此,客户端不会耦合到API本身,而是耦合到可以动态添加的媒体类型。