如果它们应该使用HATEOAS,为什么要记录RESTful API?

时间:2015-04-08 01:20:46

标签: rest hateoas

为了掌握RESTful API的基本目的,我已经开始深入研究HATEOAS

根据维基百科页面,

  

除了对超媒体的一般理解之外,REST客户端不需要有关如何与任何特定应用程序或服务器交互的先验知识。相比之下,在面向服务的体系结构(SOA)中,客户端和服务器通过文档或接口描述语言(IDL)共享的固定接口进行交互。

现在,我并不真正理解这应该如何运作,除非事先知道API中可用的内容,这会谴责HATEOAS的明确目的。事实上,Swagger等工具的存在是为了记录RESTful API。

因此,虽然我理解HATEOAS可以允许Web服务指示资源的状态,但是我错过了链接(haha),它展示了客户端应用程序如何可能弄清楚如何处理返回的后续操作缺少某种固定界面的链接"。

HATEOAS应如何实现这一目标?

2 个答案:

答案 0 :(得分:8)

你让事情变得混乱。像Swagger这样的工具不存在用于记录RESTful API的明确目的。它们的存在是为了记录非RESTful的HTTP API!对于非超文本驱动的API,您需要这样的工具,并且需要关注URI语义和方法而不是媒体类型的文档。所有那些生成URI和HTTP方法列表的花哨工具都与您在REST中应该做的完全相反。引用Roy Fielding关于此事:

  

REST API应该花费几乎所有的描述性工作   定义用于表示资源和驾驶的媒体类型   应用程序状态,或定义扩展关系名称和/或   支持超文本的标记,用于现有标准媒体类型。任何   花费在描述哪些方法用于感兴趣的URI上的努力   应该在处理规则的范围内完全定义   对于媒体类型(在大多数情况下,已经由现有类型定义)   媒体类型)。 [失败在这里意味着带外信息是   推动互动而不是超文本。]

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

HATEOAS并不排除对所有文档的需求。 HATEOAS允许您将文档集中在媒体类型上。您的应用程序应该符合底层协议 - 大部分时间都是HTTP - 并且该协议的权威文档是您的驱动交互所需的所有客户端。但他们仍然需要知道他们正在与之互动。

例如,当您输入Stack Overflow时,您知道有用户,问题和答案。您需要有关这些内容的文档,但是您不需要详细说明链接或按钮上的单击操作的文档。您的浏览器已经知道如何驱动它,这就是它在其他地方的工作方式。

引用another answer,REST是网络本身的架构风格。当您输入Stack Overflow时,您知道用户,问题和答案是什么,您知道媒体类型,并且网站为您提供了指向它们的链接。 REST API必须执行相同的操作。如果我们按照人们认为应该完成REST的方式设计Web,而不是让主页上有问题和答案的链接,我们会有一个静态文档解释为了查看问题,你必须采用URI stackoverflow .com / questions /,用Question.id替换id并将其粘贴到您的浏览器上。这是无稽之谈,但这就是许多人认为REST的原因。

答案 1 :(得分:2)

根据客户与服务互动的自主程度,这个问题有各种答案......

让我们首先看一下人类驱动的客户端 - 浏览器。浏览器对银行,音乐会,猫以及网上发现的任何其他内容一无所知 - 但它肯定知道如何呈现HTML。 HTML是一种支持超媒体(链接和表单)的媒体类型。在这种情况下,您拥有一个完美的应用程序,其客户端只能理解通用超媒体。这里的“固定界面”是HTML。

然后我们拥有自治客户端或“脚本化”客户端,这些客户端应该与服务进行交互而无需人工干预。这可能是您在将REST与SOA(P)进行比较时考虑的那种客户端。您可以在集成方案中找到此类客户端,其中两个独立的计算机系统以某种预定义的方式交换数据。

此类自治客户必须同意某事以便彼此互动。问题是这个“某事”是或不是。

在面向服务的体系结构中,客户端就特定的URL /端点以及在这些端点(RPC)上调用的特定“方法”达成一致 - 这会在所使用的URL结构上添加耦合。它还强制客户端知道在哪种服务上调用哪种方法 - 服务器无法更改URL,也无法在不破坏客户端的情况下将“方法”从一个服务移动到另一个服务。

基于REST /超媒体的系统表现不同。在这样的系统中,客户端和服务器在一个公共条目URL上达成一致,其中客户端可以在运行时查找(GET)服务文档,使用诸如链接或表单之类的超媒体控件来描述与服务器的所有可能的交互。这些超媒体控件通知客户端如何与服务进行交互(HTTP方法和有效负载编码)和 以与服务进行交互。这实际上意味着我们不再拥有“服务”,但可能有许多不同的服务,因为客户端将在运行时告知在何处以及如何与客户进行交互。

那么客户端如何知道它应该寻找哪些超媒体控件呢?它通过同意服务器将用于识别相关控件的一组标识符来实现。对于链接,这通常被称为“链接关系类型”。

这引导我们看到服务器和客户端达成共识的那种“东西” - 它是1)支持超媒体的媒体类型,2)根服务索引URL,3)超媒体控制标识符和4)每个控件的预期有效负载。在运行时,客户端然后发现剩余的URL,HTTP方法和有效负载编码(例如JSON,XML或URL编码的键/值对)。

目前,有一小组用于超媒体API的通用媒体类型--Mason,HAL,Sirene,Collection JSON,Hydra for JSON-LD以及其他一些媒体类型。

如果您有兴趣,我会在各种博客文章中介绍这个主题: