想象一下,我有一个完全实现的REST API,它也提供了HATEOAS。
假设我浏览了根目录,除了自我链接之外,还返回了另外两个链接(例如一个用于/users
,一个用于/orders
)。据我所知,HATEOAS消除了对带外信息的需求。客户应该如何知道users
的含义?存储语义在哪里?
我知道这是一个愚蠢的问题,但我真的很想知道。
答案 0 :(得分:14)
假设您刚刚发现Twitter并且第一次使用它。在Web浏览器中,您会看到一列段落,其中包含遍布页面的大量链接。你知道做某事的方法,但你并不知道具体的行动。你怎么知道它们是什么?
嗯,你看看链接并考虑他们的名字是什么意思。有些人会立即根据惯例认出:作为一名经验丰富的Web用户,您可以非常清楚点击" home"," search"并且"退出"链接意味着完成。
但是其他链接有你不认识的名字。什么"转推"做? 那个小星星图标做了什么?
基本上有两种方法可以解决这个问题:
通过实验,也就是说,点击链接并查看发生的情况,然后从结果中获取每个链接的含义。
通过某些带外信息的来源,例如在线帮助,通过Google搜索找到的教程或坐在您旁边的朋友解释网站的工作原理。
REST API也是如此。 (回想一下,REST旨在模拟Web实现与人类交互的方式。)
虽然原则上计算机(或API客户端开发人员)可以通过实验推断出链接关系的语义,但显然这并不实用。离开
惯例,基于例如the IANA ' list of standardized link relations及其含义。
带外信息,例如API文档。
REST的概念没有任何不一致之处,要求客户端开发人员依赖API本身以外的东西来理解链接关系的含义。这是使用网站的人类的标准做法,使用网站的人是REST模型。
REST实现的目标是不再需要有关与API交互的机制的带外信息。回到Twitter的例子,你可能不得不让某人在某个时候向你解释什么,确切地说,"转推"链接呢。但是你没有必须知道要输入的特定URL以使转推发生,或者你想要作出的推文的ID号,甚至是推文拥有唯一ID。网络设计意味着,一旦您确定要点击哪个链接,就会为您解决所有这些复杂问题。
因此使用REST API。确实,在大多数情况下,计算机或程序员只需要告知每个链接关系的含义。但是一旦他们掌握了这些信息,他们就可以浏览整个API,而无需了解 else 关于它们如何组合在一起的详细信息。
答案 1 :(得分:1)
REST不会消除对带外信息的需求。您仍然需要记录您的媒体类型。 REST消除了客户端与API底层协议交互时对带外信息的需求。
语义由媒体类型记录。您的API根目录是媒体类型的资源,比如说application/vnd.mycompany.dashboard.v1+json
之类的内容,该媒体类型的文档会解释链接关系users
会导致application/vnd.mycompany.user.v1+json
的集合与当前经过身份验证的用户相关,orders
指向application/vnd.mycompany.order.v1+json
。
图书馆类比在这里工作。当你在一本书之后进入图书馆时,你知道如何阅读一本书,你知道如何走到书架并拿起书,你知道如何向图书管理员询问方向。每个图书馆可能有不同的布局,书架的组织可能不同,但只要你知道你在寻找什么,而你和图书管理员说同一种语言,你就可以找到它。然而,期望图书管理员教你一本书的内容太过分了。