adn*_*nan 1 rest api-design hateoas hypermedia json-api
我试图围绕如何(以及是否要)在我的api中实现HATEOAS进行研究。我喜欢这样一种概念:仅向客户提供在当前情况下适当的操作。但是我不确定我是否正确实现了这个想法。
假设我有一个资源类型订单,其状态可以更改,它可以具有不同的状态(处理中,接受,拒绝,过期,成功)。然后,我应该创建以下json对象:
{
...
"links": {
"accept": "http://example.com/order/1/accept",
"decline": "http://example.com/order/1/decline"
}
}
Run Code Online (Sandbox Code Playgroud)
还是我在这里创建不必要的动作?如果以上正确,是否应通过PATCH或GET更改状态?如果是PATCH,一个人怎么会知道(打败了超媒体的目的)?
编辑:忘记添加订单ID
假设我有一个资源类型订单,其状态可以更改,它可以具有不同的状态(处理中,接受,拒绝,过期,成功)。
警告:除非您的域恰好是文档管理,否则如果您尝试将资源与域概念进行匹配,可能会陷入混乱。吉姆•韦伯(Jim Webber)在几年前就警告过 ; 在大多数情况下,您的资源是集成域的一部分。它们是用于与您的域模型进行交互的数字小纸片。
{
...
"links": {
"accept": "http://example.com/order/accept",
"decline": "http://example.com/order/decline"
}
}
Run Code Online (Sandbox Code Playgroud)
这里的基本思想很好-如果客户端要调用accept协议,则他们知道要使用哪个链接。对于拒绝协议也是如此。除此之外,客户端知道它不应该尝试这样做,因为链接不可用。例如,如果客户的目标是使订单期满,它将知道它已经陷入了死胡同。
URI的拼写有点奇怪。客户不需要关心拼写,但是请求应该是无状态的。如果订单是一个类型的资源,那么你是如何沟通,接受/拒绝顺序。
如果以上正确,是否应通过PATCH或GET更改状态?
都不行
GET是错误的,因为广告宣传一种资源支持GET的说法是操作是安全的,这意味着中介组件可以推测性地跟踪该链接,从而预先加载结果以节省客户端时间。如果您了解传达客户决定的信息,那不是您想做的事情
PATCH有两个问题。首先,它是为文档操作而设计的;如果您的应用程序是文档数据库,那么PATCH非常适合进行一个或多个范围更改。但是,处理业务模型的代理表示不是很好。而不是客户端将其意图传达给服务器,客户端将其意图传达给表示形式的副作用传达给客户,然后服务器尝试从副作用中推断出意图。
但是您可能会解决这个问题;毕竟,您可以选择支持的媒体类型,并可能将自己限制在那些可以表达客户意图的媒体类型上。
第二个问题是PATCH不是幂等的。它具有与POST相同的失败模式-如果服务器未确认该请求,则客户端无法轻易确定重试该请求是否安全。
直截了当的方法是将编辑视为将手写笔记放入某人的收件箱中
订单54321应该被接受。请完成它。签名,客户端。
换句话说,我们不是在尝试直接操纵订单资源,而是将注释发送到收件箱中,这将带来操纵订单的副作用。客户端描述它想要的更改,服务器进行更改(或者,如果您允许服务器具有自主权,则不进行更改)。
对于这种方法,PUT(幂等)或POST(不合适)是合适的。实际上,您正在向收件箱集合中添加新消息,并且可以使用该惯用语来选择合适的方法。
如果是PATCH,一个人怎么会知道(打败了超媒体的目的)?
客户如何知道要在“链接”属性中寻找链接?
浏览器如何知道如何处理HTML文档中的链接?
REST的答案是:他们知道,因为您在设计媒体类型本身上投入了大量精力。就网络而言,在设计text / html媒体类型上花费了大量时间和精力,因此,任何使用html设计的客户端都可以使用共享理解的服务器产生的表示-客户端和服务器彼此分离,但具有共同点。
对于HTML,在大多数情况下,媒体类型定义了与链接关联的HTTP方法(形式是例外,它允许表示从受限集中指定方法)。站在巨人的肩膀上。
| 归档时间: |
|
| 查看次数: |
1072 次 |
| 最近记录: |