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

时间:2014-10-23 13:28:19

标签: rest sorting bulk

我们有一个大型列表("集合"),其中包含许多实体(" items")。这一切都通过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}
]

但是,如何处理此批量请求的错误?当部分更新成功时,如何发送响应?是否允许PATCH集合而不是资源?如果这是错误的思路,那么更好的方法是什么?

1 个答案:

答案 0 :(得分:6)

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

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

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

  3. 集合也是一种资源,因此将PATCH与集合一起使用并没有任何内在错误,但......

  4. PATCH请求应该具有某种diff格式作为有效负载,确定要转换的状态以及最终状态。除非你愿意使用更标准化的格式,否则我不会与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]