REST 批量删除多个项目

Wil*_*oat 5 rest http-delete

我需要在批处理中按 id 删除多个项目,但是 HTTP DELETE 不支持正文有效负载。

解决选项:

1. @DELETE /path/abc?itemId=1&itemId=2&itemId=3 on the server side it will be parsed as List of ids and DELETE operation will be performed on each item.

2. @POST /path/abc including JSON payload containing all ids. { ids: [1, 2, 3] }
Run Code Online (Sandbox Code Playgroud)

这有多糟糕,哪个选项更可取?任何替代方案?

更新:请注意,性能是这里的关键,它不是为每个单独的 id 执行删除操作的选项。

Eri*_*lli 13

多年来,很多人对此产生了疑问,我们可以在此处的相关问题中看到。似乎接受的答案范围从“肯定会这样做”到“它显然是在虐待协议”。由于许多问题是多年前发送的,让我们深入研究 2014 年 6 月的 HTTP 1.1 规范 ( RFC 7231 ),以便更好地了解哪些内容明显不受欢迎。

第一个建议的解决方法:

首先,关于第 2 节中的资源和 URI 本身:

HTTP 请求的目标称为“资源”。HTTP 不限制资源的性质;它只是定义了一个可能用于与资源交互的接口。每个资源都由统一资源标识符 (URI) 标识。

基于它,有些人可能会争辩说,由于 HTTP 不限制资源的性质,一个包含多个资源的 URIid是可能的。我个人认为这是一个解释问题。

关于您提出的第一个解决方法 ( DELETE '/path/abc?itemId=1&itemId=2&itemId=3'),我们可以得出结论,如果您将资源视为实体集合中的单个文档,则不鼓励这样做,而如果您将资源视为实体集合本身,则很好。

第二个建议的解决方法:

关于您提出的第二个解决方法 ( POST '/path/abc' with body: { ids: [1, 2, 3] }),使用POST删除方法可能会产生误导。本节第4.3.3节说,有关POST

POST 方法请求目标资源根据资源自身的特定语义处理请求中包含的表示。例如,POST 用于以下功能(以及其他功能): 向数据处理过程提供数据块,例如输入到 HTML 表单中的字段;向公告板、新闻组、邮件列表、博客或类似的文章组发布消息;创建一个尚未被源服务器识别的新资源;将数据附加到资源的现有表示中。

虽然对于 的“除其他”函数有一些解释的空间POST,但它显然与我们有DELETE移除资源的方法这一事实相冲突,正如我们在第 4.1 节中看到的:

DELETE 方法删除目标资源的所有当前表示。

所以我个人强烈反对使用POST删除资源。

另一种解决方法:

受到您的第二个解决方法的启发,我们建议再使用一个:

DELETE '/path/abc' with body: { ids: [1, 2, 3] }
Run Code Online (Sandbox Code Playgroud)

它与解决方法二中提出的几乎相同,但使用正确的 HTTP 方法进行删除。在这里,我们遇到了bodyDELETE请求中使用实体的困惑。有很多人说它无效,但让我们坚持规范的第 4.3.5 节

DELETE 请求消息中的有效载荷没有定义的语义;在 DELETE 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。

因此,我们可以得出结论,规范并没有阻止DELETE拥有body有效载荷。不幸的是,一些现有的实现可能会拒绝该请求……但这对我们今天有什么影响?

很难100%肯定,但与由现代要求fetch只是不允许bodyGETHEAD。这就是Fetch 标准第 5.3节第 34 项中所述的内容:

如果任一主体存在且非空或 inputBody 非空,并且请求的方法为 GET 或 HEAD,则抛出 TypeError。

我们可以确认它以同样的方式来实现对取pollyfill线路342

最后的硬伤:

由于HTTP 规范允许DELETE使用body有效负载的替代解决方法可行,并且所有现代浏览器都支持使用fetchpolyfill 和自 IE10 以来的 polyfill,因此我建议使用这种方式以有效且完整的工作方式进行批量删除。

  • 我认为这个答案值得点赞,因为每个人都在批评批量方法,但没有人提供解决方案。显然是有必要的! (3认同)
  • 伙计们,我非常愿意遵循正确的 HTTP 语义,但是这些方法在性能或开发工作方面都不够可行。该模块是现有架构的插件,实际上我们无法一一调用 api 1000 次,显然我们没有人力资源来实现“创造性”解决方案,我们只需要通过批量执行来完成工作。 (3认同)