【问题标题】:Rest API Hateoas : Should API response have identifiers as hard coded or as placeholders?Rest API Hateoas:API 响应应该有硬编码的标识符还是占位符?
【发布时间】:2020-04-06 14:01:15
【问题描述】:

Link to the HATEOAS 这是 Hateoas 文章的链接(下面的快照),其中资源的标识符是 URL 的一部分,即 12345。这里 API 响应具有最终的 API 相对 URL,即 /accounts/12345/deposit 和客户只需点击即可。

Link to the Github Users API 这是 Github API 的链接(下面的快照),其中有很多标识符的占位符。客户端将如何修改这些 URL 并在这些占位符中添加值?例如,{/gist_id}、{/other_user}。

传递带有 id 值而不是占位符的 URL 不是更好吗?为什么以及何时依赖不同的客户端在这些占位符中添加值?

【问题讨论】:

    标签: rest api api-design hateoas


    【解决方案1】:

    作为应用程序状态引擎 (HATEOAS) 的超文本不仅仅是链接的使用。从本质上讲,它非常成功地实施了在 Web 上使用了 20 年的交互模型。在网络上,服务器通常通过link relations 的帮助“教”客户端(浏览器)实现某些目标,这可用于自动下载相关资源或给出参考资源的提示,Web forms 定义了每个支持的(输入)元素的语法和语义,即文本字段、用于选择一个或多个选项的选项元素、下拉菜单甚至滑块小部件。基于每个元素的affordance,客户端知道,即一个按钮想要被点击或按下,而一个文本字段想要一些用户输入和东西或带有prefetch链接关系名称注释的链接可以自动下载一旦当前页面完成加载,客户端可能会在接下来调用它,或者preload 链接关系可能会指示用户代理在当前页面加载过程的早期加载引用的资源。

    该表单不仅向客户端介绍了资源所支持的字段,还向客户端介绍了将请求发送到的目标 URI、发送请求时使用的 HTTP 方法以及媒体类型,在这种情况下of Web 表单通常隐式设置为application/x-www-form-urlencoded

    在理想情况下,客户端只使用服务器提供的信息。不幸的是,世界并不完美,随着时间的推移,人们提出了许多其他解决方案。其中之一是URI templating,它基本上允许客户端使用基本 URI 并用具体值填写某些占位符。由于使用模板需要了解 URI 意图或您需要传递的参数,因此此类功能仅作为媒体类型支持的一部分才有意义。

    Plain JSON (application/json) 默认情况下不支持任何 URI,因此接收纯 JSON 有效负载的用户代理可能无法自动将模板 URI 替换为开箱即用的具体 URI。 JSON Hyper-Schema (application/schema+json) 尝试将链接和 URI 模板支持添加到纯 JSON 有效负载。但是,用户客户端需要使用适当的媒体类型来提示,以便自动解析完整的 URI。因此,用户代理还必须支持相应的媒体类型,否则它将无法成功处理文档(将模板 URI 解析为真实 URI)。

    JSON 超文本应用程序语言又名HAL JSON 也支持链接的 URI 模板。 application/collection+json 确实支持两种模板 - query templatesobjects-template。第一个类似于 URI 模板,允许在发送请求时将某些查询参数附加到目标 URI,而后者允许定义一个完整的对象,该对象包含用于在集合中添加或编辑项目的所有输入元素. JSON-LD 并不真正支持 URI 模板 AFAIK,尽管它使用所谓的上下文的概念,其中某些术语可用于缩写 URI。因此,name 之类的内容可以在 http://schema.org/name 之类的 URI 的上下文中使用。

    如您所见,对 URI 模板的支持取决于用于交换数据的媒体类型。在概述的 github 示例 GET /users/:username 的情况下,这或多或少类似于典型的 Web API 文档,类似于在 Swagger API documentation 中所做的,不幸的是 has hardly anything to do with HATEOAS

    【讨论】:

      【解决方案2】:

      对于您的顶级示例(银行),您绝对应该包含完整的 URL 和帐号 (ID),这样客户就不需要翻译/替换任何内容。这是 HATEOAS 最常见的情况。但是,GitHub 确实为可能包含多个值的端点提供了那些“占位符”。您不能在响应中包含每个用户的“following_url”,这是不切实际的。因此,您必须以另一种方式确定“other_user”值并进行替换。就个人而言,我的任何应用程序都没有这个用例,而且我所有的 HATEOAS URL 都与您的第一个示例相似(尽管我更喜欢完整的 URL,而不是相对的)。除非你有像 GitHub 那样的特殊情况,否则没有必要使用这些占位符。甚至 GitHub 也只使用它们可能是多个值的地方。对于固定值 URL,它们在 URL(“octocat”)中包含用户名(如您的帐号)。

      【讨论】:

        【解决方案3】:

        据我说,我们不应该在正文中给出直接 url 我们应该始终参数化 api 并在那里获取详细信息。 在简单的情况下,如果数据的 Id 比每次需要更新详细 url 的数据时发生变化。 否则,如果它是动态的,您将永远不会遇到这个问题。 这也属于最佳做法。

        【讨论】:

        • 是的,我认为这是一种正确的方法,因为我们的数据库中没有单一的真理,而且数据库可能会不断改变这种方法似乎很好。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-14
        • 2020-07-08
        • 2017-12-18
        • 2012-10-13
        • 1970-01-01
        • 1970-01-01
        • 2016-02-18
        相关资源
        最近更新 更多