简体   繁体   English

在现实世界中使用Restful Web服务是否值得实现HATEOAS?

[英]Is it Worth Achieving HATEOAS for Restful Web Services In Real World Usage?

I have been reading a lot about the potential benefits if I were to convert my existing Restful web services to be as HATEOS as possible. 如果我将现有的Restful Web服务转换为尽可能的HATEOS,我一直在阅读很多关于潜在好处的内容。 I understand the importance in providing links in the payload to reduce the consumer's burden in remembering the next valid available actions. 我理解在有效负载中提供链接的重要性,以减少消费者在记住下一个有效可用操作时的负担。 However, I can't seem to wrap my head around how it will help the consumer of my Restful web services in reality. 但是,我似乎无法理解它将如何帮助我的Restful Web服务的消费者实际上。

To illustrate, I take this example from Rest In Practice book about making a coffee order:- 为了说明这一点,我从“ 休息实践”一书中摘取了关于制作咖啡订单的例子: -

<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>

Basically, this allows the consumer to make a payment defined by the <link> tag. 基本上,这允许消费者进行由<link>标签定义的支付。 However, in reality, the consumer still needs to know all the semantics of that web service call, for example, what method (POST or PUT) to use, what request parameters to use in the payload in order to make the payment, etc... in another word, the consumer still needs to rely on the WADL documentation to know how to make invoke this web service successfully. 然而,实际上,消费者仍然需要知道该Web服务调用的所有语义,例如,使用什么方法(POST或PUT),在有效载荷中使用哪些请求参数以进行支付等。换句话说,消费者仍然需要依赖WADL文档来了解如何成功调用此Web服务。 These tags probably make more sense if they are all using GETs on one specific item. 如果他们都在一个特定项目上使用GET,这些标签可能更有意义。 Otherwise, I really don't see much benefits in defining the links here... apart from the fact the consumer knows what actions they can invoke next, and then refer to the WADL to determine how to invoke it correctly. 否则,我真的没有看到在这里定义链接的好处...除了消费者知道他们接下来可以调用什么动作的事实,然后参考WADL来确定如何正确地调用它。

My next concern is the possibility of ending up with a very heavy payload with all the <link> tags. 我的下一个问题是有可能以所有<link>标签结束非常重的有效载荷。 For example, if a GET on /projects/1/users returns all the user information that belong project 1, I assume I will end up with the following tags:- 例如,如果/ 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>

If a project contains say, 500 users... wouldn't I have 500 user links in the payload? 如果一个项目包含说,500个用户......我不会在有效负载中有500个用户链接吗? Otherwise, what is the best approach in redesigning my web services to handle this situation? 否则,重新设计我的Web服务以处理这种情况的最佳方法是什么? Or is this acceptable in real world? 或者这在现实世界中是否可以接受?

Any thoughts or suggestions are greatly appreciated here. 任何想法或建议在这里都非常感激。 Thank you. 谢谢。

To think of why it's the right thing to do, imagine your API without a HATEOAS approach: you'll have to publish every single possible URI scheme in your documentation (or in your WADL, if that's your thing), and from that point on you cannot change them without breaking your clients. 想想为什么这是正确的做法,想象你的API没有HATEOAS方法:你必须在你的文档中(或在你的WADL,如果这是你的东西)发布每个可能的URI方案,并从那时开始如果不打破你的客户,你就无法改变它们

In essence, your clients will be inextricably coupled to your choice of URI layout. 从本质上讲,您的客户将与您选择的URI布局密不可分。 That's a level of coupling that you can easily avoid by just documenting where the links are in your media types rather than documenting what the links look like as well. 这是一种耦合程度,您只需记录链接在媒体类型中的位置,而不是记录链接的外观 ,即可轻松避免。

That said, it might be OK for your application's needs to take that approach, and that's fine. 也就是说,您的应用程序可能需要采用这种方法,这很好。 Just keep in mind that you'll be stuck with your URI layout for a long, long time. 请记住,您将长时间陷入URI布局。 You'll be in good company though. 不过你会很好

For your particular example, I think it makes sense to go back to HTML. 对于您的特定示例,我认为回归HTML是有意义的。 If you display a list of 500 resources in HTML, would you include a link to each resource, so that users can get more information? 如果您在HTML中显示500个资源的列表,是否会包含指向每个资源的链接,以便用户可以获得更多信息? You probably would. 你可能会。 A REST API is not much different - if you return a list of 500 resources, you need to include 500 links, so that users can get more information about each resource. REST API没有太大区别 - 如果返回500个资源的列表,则需要包含500个链接,以便用户可以获得有关每个资源的更多信息。

Expecting clients to build up URLs based on some IDs or names would be like asking users to manually type URLs in the browser's address bar. 期望客户基于某些ID或名称构建URL就像要求用户在浏览器的地址栏中手动键入URL。

Here is a very good article about this, in particular: 这是一篇非常好的文章 ,特别是:

Just like HTML files link to each other with tags, or just like XML files link to each other with XLink, all state transfer has to be done solely as a reaction to a link found inside of a representation 就像HTML文件通过标签相互链接一样,或者就像XML文件通过XLink链接到彼此一样,所有状态转移都必须完全作为对表示内部链接的反应

Just a side-point on the 500 user thing: I'm no expert but my understanding is that you can restfully provide pagination: 只是关于500用户事物的一个侧面点:我不是专家,但我的理解是你可以安静地提供分页:

/project/1/users/pages/1 /项目/ 1 /用户/页/ 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>

This isn't really an answer, just some tips for adopting HATEOAS. 这不是一个真正的答案,只是一些采用HATEOAS的技巧。 You do not need to include hundreds of links, you can either include 1 link to the full list of 500, 1 link to a paginated subset of the links, or include a paginated subset in the response and add a next page link. 您不需要包含数百个链接,您可以包含指向500的完整列表的1个链接,指向链接的分页子集的1个链接,或者在响应中包含分页子集并添加下一页链接。

In response to the WADL thing, you should use the built-in facilities of whatever your content format is, eg In HTML that would be LINK and A elements to indicate the client should make GET requests, and FORM elements for POST requests. 为了响应WADL的事情,您应该使用内容设置,无论您的内容格式是什么,例如在HTML中, LINKA元素表示客户端应该发出GET请求,以及FORM元素用于POST请求。 Obviously other formats and APIs XLink and XMLHTTPRequest support HTTP better than HTML does. 显然,其他格式和API XLink和XMLHTTPRequest比HTML支持HTTP更好。 You might like to look at http://tools.ietf.org/html/draft-nottingham-link-hint 您可以查看http://tools.ietf.org/html/draft-nottingham-link-hint

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM