HATEOAS和链接/动作 [英] HATEOAS and links/actions

查看:142
本文介绍了HATEOAS和链接/动作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力解决如何(以及是否要)在我的api中实现HATEOAS.我喜欢这样一种概念:仅向客户提供在当前情况下适当的操作.但是我不确定我是否正确实现了这个想法.

I'm trying to wrap my head around how to (and if to) implement HATEOAS in my api. I like one of the concept of feeding the client only actions that are appropriate in the current situation. However I'm not sure if I'm implementing this idea correctly.

假设我有一个资源类型 order ,其状态可以更改,它可以具有不同的状态(处理接受拒绝过期,成功).然后,我应该创建以下json对象吗?

Let's say I have a resource type order with a status that can be changed, it can have different statuses (processing, accepted, declined, expired, successful). Should I then create the following json object:

{
    ...
    "links": {
        "accept": "http://example.com/order/1/accept",
        "decline": "http://example.com/order/1/decline"
    }
}

还是我在这里创建不必要的操作?如果以上正确,是否应通过PATCH或GET更改状态?如果是PATCH,一个人怎么会知道(打败了超媒体的目的)?

Or am I creating unnecessary actions here? And if above is correct, should the status be changed by a PATCH, or GET? And if it were PATCH, how would one know (defeating the purpose of hypermedia)?

修改:忘记添加订单ID

Forgot to add order id

推荐答案

比方说,我有一个资源类型订单,其状态可以更改,它可以具有不同的状态(处理中,接受,拒绝,过期,成功).

Let's say I have a resource type order with a status that can be changed, it can have different statuses (processing, accepted, declined, expired, successful).

警告:除非您的域恰好是文档管理,否则如果您尝试将资源与域概念进行匹配,您可能会陷入困境.吉姆·韦伯警告大约在几年前;在大多数情况下,您的资源是集成域的一部分.它们是用于与您的域模型进行交互的数字小纸片.

Warning: unless your domain happens to be document management, you may be getting yourself into a tangle if you try to match your resources with your domain concepts. Jim Webber warned about this years ago; in most cases, your resources are part of the integration domain. They are little digital pieces of paper that are used to interact with your domain model.

{
    ...
    "links": {
        "accept": "http://example.com/order/accept",
        "decline": "http://example.com/order/decline"
    }
}

这里的基本思想很好-如果客户端要调用accept协议,则他们知道要使用哪个链接;对于拒绝协议也是如此.除此之外,客户端知道它不应该尝试这样做,因为链接不可用.例如,如果客户的目标是使订单期满,它将知道它已经陷入了死胡同.

The basic idea here is fine - if the client wants to invoke the accept protocol, they know which link to use; likewise for the decline protocol. Anything else, the client knows it shouldn't be trying to do because the links are not available; for instance, if the goal of the client was to expire the order, it would know that it had run into a dead end.

这里URI的拼写有点奇怪;客户不需要关心拼写,但是请求应该是无状态的.如果订单是资源的类型,那么您如何传达接受/拒绝订单的方式.

The spelling of the URI here is a bit strange; the client shouldn't need to care about the spelling, but the request should be stateless. If order is a type of resource, then how are you communicating which order to accept/decline.

如果上述正确,是否应通过PATCH或GET更改状态?

And if above is correct, should the status be changed by a PATCH, or GET?

都不是.

GET 是错误的,因为宣传资源支持GET的广告声称该操作是安全,这意味着中介组件可以推测性地跟随该链接,加载结果以节省客户端时间.如果您了解消息以传达 client

GET is wrong, because advertising that a resource supports GET is a claim that the operation is safe, which means that intermediary components can speculatively follow the link, pre-loading the result to save the client time. Not what you want to be doing if you are understanding the message to communicate a decision made by the client

PATCH 有两个问题.首先,它是为文档操作而设计的;如果您的应用程序是文档数据库,那么PATCH非常适合进行一个或多个范围更改.但是,处理业务模型的代理表示不是很好.而不是客户端将其意图传达给服务器,而是客户端传达了其意图会对表示形式产生的副作用,然后服务器尝试从副作用中推断出意图.

PATCH has two issues. First, it's designed for document manipulation; if your application is a document database, then PATCH is fantastic for making one or several scoped changes. But it's not so great for dealing with proxy representations of the business model; instead of the client communicating its intent to the server, the client communicates the side effect that its intent would have on the representation, and then the server tries to deduce the intent from the side effect.

但是您可能会解决这个问题;毕竟,您可以选择支持的媒体类型,并可能将自己限制在那些可以表达客户意图的媒体类型上.

But you could potentially get around that; after all, you can choose the media types your support, and could potentially limit yourself to those types which allow you to express the client's intent.

第二个问题是PATCH不是幂等的;它具有与POST相同的失败模式-如果服务器未确认该请求,客户端将无法确定重试该请求是否安全.

The second issue is that PATCH is not idempotent; it has the same failure modes as a POST -- if the request isn't acknowledged by the server, the client's cannot readily determine if it is safe to retry the request.

直接的方法是将编辑内容视为将手写笔记放入某人的收件箱中

The straight forward approach is to think of the edits as analogous to putting a hand written note into somebody's inbox

应接受54321号命令.请完成它. 签名,客户端.

Order 54321 should be accepted. Please get it done. Signed, the client.

换句话说,我们不是在尝试直接操纵订单资源,而是将注释发送到收件箱中,这将带来操纵订单的副作用.客户端描述了它想要的更改,服务器进行了更改(或者,如果您允许服务器具有自主权,则不进行更改).

In other words, we aren't trying to manipulate the order resource directly, but instead delivering a note to an inbox that will have the side effect of manipulating the order. The client describes the change it wants, the server makes the change (or not, if you are allowing the server to have autonomy).

对于这种方法,PUT(幂等)或POST(不合适)是合适的.实际上,您正在向收件箱集合中添加新消息,并可以使用该惯用语来选择合适的方法.

For this approach, PUT (which is idempotent) or POST (which is not) are appropriate. In effect, you are adding a new message to the inbox collection, and can use that idiom to choose the suitable method.

如果是PATCH,人们怎么会知道(打败了超媒体的目的)?

And if it were PATCH, how would one know (defeating the purpose of hypermedia)?

客户如何知道要在链接"属性中查找链接?

How would the client know to look for links in the "links" property?

浏览器如何知道如何处理HTML文档中的链接?

How does the browser know what to do with the links in an HTML document?

REST的答案是:他们知道,因为您在设计媒体类型本身上投入了大量精力.在网络的情况下,在设计text/html媒体类型上花费了大量时间和精力,因此,任何使用html设计的客户端都可以使用共享理解的服务器产生的表示-客户端和服务器相互分离,但具有共同点.

The REST answer is: they know because you've invested a bunch of effort in designing the media type itself. In the case of the web, a bunch of time and effort was invested in designing the text/html media type, and so any client that is designed with html in mind can consume the representation produced by a server that shares that understanding -- the client and server are decoupled from each other, but share a common ground.

对于HTML,在大多数情况下,媒体类型定义了与链接关联的HTTP方法(形式是例外,它允许表示形式从受限制的集合中指定方法).站在巨人的肩膀上.

In the case of HTML, for the most part the media type defines the HTTP methods associated with the links (the exception being forms, which allows the representation to specify a method from a restricted set). Stand on the shoulders of giants.

这篇关于HATEOAS和链接/动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆