集合上的 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-Since
或 If-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 以批量更新排序参数的主要内容,如果未能解决你的问题,请参考以下文章