我们有一个包含许多实体("项目")的大列表("集合").这一切都通过RESTful接口进行管理.可以通过项目上的order属性手动对项目进行排序.查询时,数据库会根据订单列出集合中的所有项目.
现在,我们希望将此机制公开给用户,他们可以在一个调用中更新所有项目的完整排序.数据库不允许order相同collection_id(唯一collection_id+ order)相同,因此您不能(绝对不应)逐个更新所有项目.
我想到了PATCH请求,但没有考虑资源,所以
PATCH /collections/123/items/
Run Code Online (Sandbox Code Playgroud)
身体像
[
{'id': 1, 'order': 3},
{'id': 2, 'order': 1},
{'id': 3, 'order': 2}
]
Run Code Online (Sandbox Code Playgroud)
但是,如何处理此批量类型的请求的错误?当部分更新成功时,如何发送响应?是否允许PATCH集合而不是资源?如果这是错误的想法,那么更好的方法是什么?
首先,在最后一段回答你的问题:
如何处理批量请求中的错误很大程度上取决于请求.在你的情况下,我认为不应该允许部分成功,你应该回滚整个操作并返回错误,因为失败的唯一原因是有人处理过时的表示.例如,当您批量创建或删除资源时,可以接受部分成功.
您可以使用207 Multi-StatusHTTP代码处理批量请求中的错误.这是一个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"}]
Run Code Online (Sandbox Code Playgroud)
当然,如果客户不关心当前订单,他可以删除test操作.您也可以使用If-Unmodified-Since或If-Match标题添加前置条件.
您可能已经注意到上面的格式是完全通用的,并且没有直接耦合到您正在更改的资源.您可以以通用方式实现上述内容,并重用PATCH它以在API中的任何位置实现它.
无论如何,你的情况很简单,我会通过使用简单,平面格式的订单的另一个资源来做到这一点.像这样的东西,返回当前顺序中的id列表:
GET /collections/123/items/ordering
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
您可以通过以下方式更改订单:
PUT /collections/123/items/ordering
[2, 3, 1]
Run Code Online (Sandbox Code Playgroud)