集合上的 Restful PATCH 以批量更新排序参数

Posted

技术标签:

【中文标题】集合上的 Restful PATCH 以批量更新排序参数【英文标题】:Restful PATCH on collection to update sorting parameter in bulk 【发布时间】:2014-12-19 04:29:24 【问题描述】:

我们有一个包含许多实体(“项目”)的大列表(“集合”)。这一切都通过 RESTful 接口进行管理。这些项目可以通过项目上的order 属性手动排序。查询时,数据库会根据顺序列出集合中的所有项目。

现在我们希望向用户公开这种机制,让他们可以在一次调用中更新所有项目的完整排序。数据库不允许相同的order 用于相同的collection_id(唯一的collection_id + order),因此您不能(而且绝对不应该)一一更新所有项目。

我想到了一个 PATCH 请求,但不是在资源上,所以

PATCH /collections/123/items/

身体像

[
  'id': 1, 'order': 3,
  'id': 2, 'order': 1,
  'id': 3, 'order': 2
]

但是,对于这种批量类型的请求,您如何处理错误?当某些更新部分成功时,您如何发送响应?是否允许修补集合而不是资源?如果这是错误的思路,还有什么更好的方法?

【问题讨论】:

【参考方案1】:

首先,在最后一段回答你的问题:

    如何处理批量请求中的错误很大程度上取决于请求。在您的情况下,我认为不应允许部分成功,您应该回滚整个操作并返回错误,因为失败的唯一原因是有人处理过时的表示。例如,当您批量创建或删除资源时,可以接受部分成功。

    您可以使用207 Multi-Status HTTP 代码处理批量请求中的错误。这是一个 WebDAV 代码,但它现在已经很标准了。响应应该是一个文档,其中包含每个项目的详细 HTTP 状态代码和消息。

    集合也是一种资源,因此将PATCH 与集合一起使用并没有本质上的错误,但是...

PATCH 请求应具有某种差异格式作为有效负载,确定您要转换的状态和最终状态。除非您愿意使用更标准化的格式,否则我不会选择 PATCH 来做您想做的事。您可能想检查json-patch 格式,在当前订单和所需订单之间创建一个差异,看看您是否喜欢这种格式。例如,在您的情况下,它将类似于:

["path": "/0/order", "value": 1, "op": "test", 
 "path": "/0/order", "value": 2, "op": "replace", 
 "path": "/1/order", "value": 2, "op": "test", 
 "path": "/1/order", "value": 3, "op": "replace",
 "path": "/2/order", "value": 3, "op": "test",  
 "path": "/2/order", "value": 1, "op": "replace"]

当然,如果客户不关心当前的订单,他可以去掉test操作。您也可以使用 If-Unmodified-SinceIf-Match 标头添加前提条件。

您可能注意到上面的格式是完全通用的,并且与您正在更改的资源没有直接耦合。您可以以通用方式实现上述内容,并在 API 中任何您需要的地方重用它来实现 PATCH

无论如何,您的情况很简单,我可以通过使用另一个具有简单、平面格式的订单的资源来做到这一点。像这样,按当前顺序返回一个 id 列表:

GET /collections/123/items/ordering

[1, 2, 3]

您可以通过以下方式更改顺序:

PUT /collections/123/items/ordering
[2, 3, 1]

【讨论】:

很好的答案。是的,我可以创建另一个用于排序的端点。我想我应该考虑 $collection 和 $collection/$id,但你可以创建一个更简单的子 /ordering。我会采用这种方法:)

以上是关于集合上的 Restful PATCH 以批量更新排序参数的主要内容,如果未能解决你的问题,请参考以下文章

HTTP Restful 语义版本控制

RESTful

RESTFul 中PUT POST PATCH的区别

RESTFul中的那些事----怎样支持RESTFul的HTTP Patch方法?

RESTful 的学习总结

如何设计一个多条件查询的restfulAPI