我需要在批处理中按 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 方法进行删除。在这里,我们遇到了body在DELETE请求中使用实体的困惑。有很多人说它无效,但让我们坚持规范的第 4.3.5 节:
DELETE 请求消息中的有效载荷没有定义的语义;在 DELETE 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。
因此,我们可以得出结论,规范并没有阻止DELETE拥有body有效载荷。不幸的是,一些现有的实现可能会拒绝该请求……但这对我们今天有什么影响?
很难100%肯定,但与由现代要求fetch只是不允许body的GET和HEAD。这就是Fetch 标准在第 5.3节第 34 项中所述的内容:
如果任一主体存在且非空或 inputBody 非空,并且请求的方法为 GET 或 HEAD,则抛出 TypeError。
我们可以确认它以同样的方式来实现对取pollyfill在线路342。
由于HTTP 规范允许DELETE使用body有效负载的替代解决方法可行,并且所有现代浏览器都支持使用fetchpolyfill 和自 IE10 以来的 polyfill,因此我建议使用这种方式以有效且完整的工作方式进行批量删除。
| 归档时间: |
|
| 查看次数: |
6669 次 |
| 最近记录: |