18

如果我要将现有的 Restful Web 服务尽可能地转换为 HATEOS,我已经阅读了很多关于潜在好处的信息。我理解在有效负载中提供链接以减轻消费者记住下一个有效可用操作的负担的重要性。然而,我似乎无法理解它将如何在现实中帮助我的 Restful Web 服务的消费者。

为了说明,我从关于制作咖啡订单的Rest In Practice书中举了这个例子:-

<order xmlns="http://schemas.restbucks.com">
  <location>takeAway</location>
  <item>
    <name>latte</name>
    <quantity>1</quantity>
    <milk>whole</milk>
    <size>small</size>
  </item>
  <cost>2.0</cost>
  <status>payment-expected</status>
  <link rel="payment" href="https://restbucks.com/payment/1234" />
</order>

基本上,这允许消费者进行由<link>标签定义的付款。然而,实际上,消费者仍然需要知道该 Web 服务调用的所有语义,例如,使用什么方法(POST 或 PUT)、在有效负载中使用什么请求参数以进行支付等。 .. 换句话说,消费者仍然需要依赖 WADL 文档才能知道如何成功调用此 Web 服务。如果这些标签都在一个特定项目上使用 GET,则它们可能更有意义。否则,我真的看不到在这里定义链接有什么好处……除了消费者知道他们接下来可以调用什么动作,然后参考 WADL 来确定如何正确调用它。

我的下一个担忧是最终可能会导致带有所有<link>标签的非常重的有效负载。例如,如果 /projects/1/users 上的 GET 返回属于项目 1 的所有用户信息,我假设我最终会得到以下标签:-

<project>
    <users>
        <user id="12" name="mike" ... />
        <user id="23" name="kurt" ... />
        <user id="65" name="corey" ... />
    </user>
    <links>
        <link rel="self" href="http://server/projects/1/users"/>
        <link rel="create_user" href="http://server/projects/1/users"/>

        <link rel="get_user_mike" href="http://server/projects/1/users/12"/>
        <link rel="get_user_kurt" href="http://server/projects/1/users/23"/>
        <link rel="get_user_corey" href="http://server/projects/1/users/65"/>
        ...
    </links>
</project>

如果一个项目包含 500 个用户……我不会在有效负载中有 500 个用户链接吗?否则,重新设计我的 Web 服务以处理这种情况的最佳方法是什么?或者这在现实世界中是否可以接受?

任何想法或建议都非常感谢这里。谢谢你。

4

4 回答 4

9

要考虑为什么这是正确的做法,请想象您的 API 没有 HATEOAS 方法:您必须在文档中(或在您的 WADL 中,如果那是您的事情)中发布每个可能的 URI 方案,并且从那时起在不破坏客户的情况下,您无法更改它们。

从本质上讲,您的客户将与您选择的 URI 布局密不可分。这是一种耦合级别,您可以通过仅记录链接在您的媒体类型中的位置而不是记录链接的外观来轻松避免。

也就是说,您的应用程序需要采用这种方法可能没问题,这很好。请记住,您将在很长一段时间内被 URI 布局所困扰。不过,你会相处得很好

于 2012-07-03T03:44:39.453 回答
5

对于您的特定示例,我认为回到 HTML 是有意义的。如果您在 HTML 中显示 500 个资源的列表,您会为每个资源包含一个链接,以便用户可以获得更多信息吗?你可能会。一个 REST API 并没有太大的不同——如果你返回一个包含 500 个资源的列表,你需要包含 500 个链接,这样用户才能获得关于每个资源的更多信息。

期望客户端基于某些 ID 或名称构建 URL 就像要求用户在浏览器的地址栏中手动键入 URL。

这是一篇非常好的文章(死链接),特别是:

就像 HTML 文件通过标签相互链接,或者就像 XML 文件通过 XLink 相互链接一样,所有状态传输都必须仅作为对在表示中找到的链接的反应来完成

于 2012-07-03T08:32:27.107 回答
0

这并不是真正的答案,只是采用 HATEOAS 的一些提示。您不需要包含数百个链接,您可以包含 1 个链接到 500 个完整列表,1 个链接到链接的分页子集,或者在响应中包含一个分页子集并添加下一页链接。

为了响应 WADL,您应该使用任何内容格式的内置设施,例如在 HTML 中,LINK以及A指示客户端应该发出 GET 请求的FORM元素和用于 POST 请求的元素。显然,其他格式和 API XLink 和 XMLHTTPRequest 比 HTML 更好地支持 HTTP。您可能想查看https://datatracker.ietf.org/doc/html/draft-nottingham-link-hint

于 2013-09-28T18:59:45.983 回答
0

只是关于 500 个用户的问题:我不是专家,但我的理解是您可以放心地提供分页:

/project/1/users/pages/1

<links>
    ...
    <link rel="get_user_mike" href="http://server/projects/1/users/12"/>
    <link rel="get_user_kurt" href="http://server/projects/1/users/23"/>
    <link rel="get_user_corey" href="http://server/projects/1/users/65"/>
    <link rel="get_page_2" href="http://server/projects/1/users/pages/2"/>
</links>
于 2013-09-28T04:29:23.617 回答