如何建模改变状态的链接关系

遵循HATEOAS原则,每个州应该超链接,建立改变资源状态的链接的最佳方式是什么?

让我们用命令来举例说明:

{
   id : 12,
   state: 'pending',
   ...,
   links: [
     ...,
     { 
       rel: 'cancel',
       href: '/orders/12/cancel'
     },
     ...
   ]
}

我对这个“/取消”部分并不满意 - 如果我可以发送带有内容的“PUT”请求,我会感觉好多了:

{
   status:'cancelled'
}

但是,我怎么用链接部分的“href”属性来表示呢? 我想在那里表示可用的行为,例如,取消订单并不总是可能的(“完成”状态)。

一种可能性是使用像'/ orders / 12?action = cancel'这样的URL,它有点像RPC方法,我错过了一些东西。

看起来可能最好的另一种可能性是有这样的链接:

{
  rel: 'cancel',
  href: '/orders/12/',
  type: 'PUT',
  values: {
    state: 'cancelled'
  }
}

这个解决方案可能会感觉有点冗长。

任何想法如何妥善处理? 也许有人已经解决了类似的“问题”?


建模资源是REST中最困难的部分。 严格遵守标准意味着如果你发现自己曾经这样做过: /resource/:id/{action} ,你违反了“正确使用HTTP”标准,因为你的终结点应该始终是“名词”,绝不是“动词“(动词是HTTP协议提供的)。

因此,尽管“取决于”(即设计资源的困难部分),但通常情况下: 对象模型状态本身可以被视为资源

这意味着,您的订单状态实际上是一个您可以查询的资源(作为独立/orderstatuses资源或作为子资源,例如/orderstatuses /orders/:id/status

您的应用程序状态现在可以根据订单本身的当前状态链接到状态资源。 如果你的'状态'模式看起来像这样(伪):

key: 'status'
values: ['pending', 'cancelled']

然后,您的应用可以将PUT /order/:id/status {status:'cancelled'} (状态良好)返回给API,然后API将取消您的订单。 这些术语有点奇怪(RPC更直观),但希望这会有所帮助。


你必须以某种方式描述表格。 你“详细”的解决方案是完全可以的:

{
  rel: 'cancel',
  href: '/orders/12/',
  type: 'PUT',
  values: {
    state: 'cancelled'
  }
}

注意:你必须定义一个自定义的MIME类型或者使用一个能够描述表单的通用MIME类型(例如collection + json),或者一个RDF类型(它支持Hydra等REST词汇) - 又名。 统一的界面/自我描述性信息

我想在那里表示可用的行为,例如,取消订单并不总是可能的(“完成”状态)。

如果操作不可用,则不要发送指向该操作的链接。


我会建议这两种模式中的任何一种。 第一种是经典的,但使用rel="edit-form"并在可用的情况下使用PATCH 。 第二种是通过横向思考HTTP资源模型如何映射到您的应用程序域模型(即,两者不必具有1:1映射)的替代方案。


解决方案1

就地编辑资源。

HTML兼容:

HTTP/1.1 200 OK
Content-Type: text/html
Location: /orders/1/

...<a rel="edit-form" href="./edit">Edit</a>...

HTTP/1.1 200 OK
Content-Type: text/html
Location: /orders/1/edit

...
<form action="../" method="POST">
    <input type="hidden" name="_METHOD" value="PATCH">
    <button type="submit" name="status" value="cancelled">Cancel Order</button>
</form>
...

POST /orders/1 HTTP/1.1
Content-Type: application/x-www-form-urlencoded

_METHOD=PATCH&status=cancelled

富客户端(例如HTML + Javascript)兼容:

PATCH /orders/1 HTTP/1.1
Content-Type: application/x-www-form-urlencoded

status=cancelled

和/或

PATCH /orders/1 HTTP/1.1
Content-Type: text/json

{
    "status": "cancelled"
}

由于HTML缺乏对HTTP的支持,因此_METHOD键是一种众所周知的方式,可以为REST框架提供正确的方法。


解决方案2

或者, 删除资源 (并且,顺便说一句,创建一个新资源

DELETE /orders/1 HTTP/1.1

HTTP/1.1 201 Created
Location: /cancelled-orders/1

有关将Web资源映射到域对象的这种方式的更多信息,请参阅我对类似问题的回答。

您可能希望阅读的另一个答案是这一个。

链接地址: http://www.djcxy.com/p/40963.html

上一篇: How to model link relations that change state

下一篇: Alternatives of using verbs and adjectives in RESTful URL