使用 REST 删除多条记录

删除多个项目的 REST-ful 方式是什么?

我的用例是,我有一个骨干集合,其中我需要能够删除多个项目一次。选择似乎是:

  1. 对每一条记录发送一个 DELETE 请求(如果有几十条记录,这似乎是一个坏主意) ;
  2. 发送一个删除,其中要删除的 ID 在 URL 中串联在一起(即,“/record/1; 2; 3”) ;
  3. 以非 REST 方式,发送一个自定义 JSON 对象,其中包含标记为删除的 ID。

所有的选择都不理想。

这似乎是 REST 约定的一个灰色地带。

132175 次浏览
  1. 是一个可行的 RESTful 选择,但显然存在您所描述的局限性。
  2. 别这样。中介机构会将其解释为“删除 /records/1;2;3上的(单个)资源”ーー因此,如果对此做出2xx 响应,可能会导致中介机构清除其高速缓存中的 /records/1;2;3; 没有清除 /records/1/records/2/records/3; 为 /records/1;2;3代理一个410响应,或者其他在您看来没有意义的事情。
  3. 这个选择是最好的, 并且可以用 REST 完成。如果您正在创建一个 API,并且您希望允许对资源进行大量更改,那么您可以使用 REST 来完成这项工作,但是具体如何做对于许多人来说并不是很明显。一种方法是到 创建“更改请求”资源(例如,将一个主体(如 records=[1,2,3])发布到 /delete-requests) ,并轮询创建的资源(由响应的 Location头指定) ,以查明您的请求是否已被接受、拒绝、正在进行或已完成。这对于长时间运行的操作很有用。另一种方法是到 向列表资源发送 PATCH请求/records,其主体包含要对这些资源执行的资源和操作的列表(以您希望支持的任何格式)。这对于快速操作非常有用,因为请求的响应代码可以指示操作的结果。

任何事情都可以在保持 REST 约束的情况下实现,通常的答案是将“问题”变成一个资源,并给它一个 URL。
因此,可以通过创建一个“批处理操作”列表并向其发布新操作来处理批处理操作,比如在此处删除、将多个项目发布到一个列表中、或对一个资源区域进行相同的编辑。

不要忘记,REST 不是解决任何问题的唯一方法。“ REST”只是一种架构风格,你不必遵循 (但是如果你不这样做,你就会失去互联网的某些好处)。我建议你看看这个 HTTP API 架构列表,选择一个适合你的。只要让自己意识到如果选择其他体系结构会失去什么,并根据用例做出明智的决定。

在 REST Web 服务中处理批处理操作的模式?上有一些关于这个问题的错误答案,它们有太多的赞成票,但是也应该被阅读。

如果 GET /records?filteringCriteria返回匹配条件的所有记录的数组,那么 DELETE /records?filteringCriteria可以删除所有这些记录。

在这种情况下,你的问题的答案将是 DELETE /records?id=1&id=2&id=3

我已经允许对集合进行大规模替换,例如 PUT ~/people/123/shoes,其中主体是整个集合表示。

这适用于客户机希望检查项目的小子集合,并删除一些项目,添加一些其他项目,然后更新服务器。他们可以放置一个空集合来删除所有。

这将意味着即使 PUT 删除了 GET ~/people/123/shoes/9,它仍然会保留在缓存中,但这只是一个缓存问题,如果其他人删除了鞋子,这将是一个问题。

我的数据/系统 API 总是使用 ETags,而不是过期时间,因此每个请求都会命中服务器,并且我需要正确的版本/并发报头来更改数据。对于只读和查看/报告对齐的 API,我确实使用到期时间来减少对原始 API 的命中,例如排行榜可以保持10分钟。

对于更大的集合,比如 ~/people,我倾向于不需要多次删除,用例倾向于不会自然产生,因此单个 DELETE 工作得很好。

以后,根据构建 REST API 的经验和遇到相同问题和需求的经验,比如审计,我倾向于只使用 GET 和 POST 动词,并围绕事件进行设计,比如 POST 地址更改事件,尽管我怀疑这会带来一系列问题:)

我还允许前端开发人员构建他们自己的 API,这些 API 使用更严格的后端 API,因为他们不喜欢严格的“ Fielding 狂热者”REST API 设计的原因通常是实用的、有效的客户端原因,以及生产率和缓存分层的原因。

我认为 Mozilla 存储服务 SyncStorage API v1.5是使用 REST 删除多条记录的好方法。

删除整个集合。

DELETE https://<endpoint-url>/storage/<collection>

用一个请求从集合中删除多个 BSO。

DELETE https://<endpoint-url>/storage/<collection>?ids=<ids>

Id : 从集合中删除 BSO,这些集合的 id 位于所提供的逗号分隔列表中。最多可以提供100个 id。

删除给定位置的 BSO。

DELETE https://<endpoint-url>/storage/<collection>/<id>

Http://moz-services-docs.readthedocs.io/en/latest/storage/apis-1.5.html#api-instructions

这似乎是 REST 约定的一个灰色地带。

是的,到目前为止,我只碰到过一个提到批处理操作(比如批处理删除)的 REST API 设计指南: 谷歌 API 设计指南

本指南 提到创建“自定义”方法,这些方法可以通过使用冒号(例如 https://service.name/v1/some/resource/name:customVerb)通过资源关联,它还明确提到批处理操作作为用例:

自定义方法可以与资源、集合或服务关联。它可以接受任意请求并返回任意响应,还支持流请求和响应。[ ... ]自定义方法应该使用 HTTP POST 谓词,因为它具有最灵活的语义[ ... ]对于性能关键的方法,它可能是有用的 提供自定义批处理方法以减少每个请求的开销

所以你可以根据谷歌的 API 指南做以下事情:

POST /api/path/to/your/collection:batchDelete

... 删除您的收集资源的一堆项目。

您可以发布一个已删除的资源:) POST /deleted-records 尸体就会 {"ids": [1, 2, 3]}