REST API 设计 - 使用请求正文删除多个项目

Posted

技术标签:

【中文标题】REST API 设计 - 使用请求正文删除多个项目【英文标题】:REST API Design - DELETE multiple items using request Body 【发布时间】:2017-06-05 14:32:04 【问题描述】:

我有一个显示供应商产品的 API

我们的用户界面将允许用户选择各种过滤条件并使用它来一次删除多个产品。

问题在于执行几千个单独的 HTTP 删除请求需要很长时间:

DELETE /api/supplier/6/products/5
DELETE /api/supplier/6/products/7
DELETE /api/supplier/6/products/8
DELETE /api/supplier/6/products/10
...

目的是进行一次 HTTP 调用以一次删除一堆供应商产品。我可以将正文传递给删除,以便它包含我们要删除的所有 ID 的列表:

DELETE /api/supplier/6/products
Body:

  "DeleteIds": "[5,7,8,10]"

在我们将它放在生产代理防火墙后面之前效果很好,该防火墙从 DELETE 请求中剥离了正文。

我查看了 HTTP 规范 RFC 2616 Fielding, et al. 并没有明确声明我不应该在 DELETE 请求中使用正文,进一步阅读表明发送正文没有任何问题带有 DELETE 请求。

我可以控制我们的代理服务器,并且能够允许所有请求通过正文,但我担心这可能不是最佳做法。我们可能有数千个 ID 需要通过,我不希望我们使用标头或 URL 参数,因为我们可能会遇到长度限制。

所以我的问题是: 使用请求正文删除多个产品的正确方法是什么?不仅仅是一种意见,还有实际的书面证据证明我为什么不应该使用 HTTP DELETE 的正文?

我应该继续吗

DELETE /api/supplier/6/products (Using a body)

或者不应该对正文使用 DELETE,而是对类似的东西进行 POST

POST /api/supplier/6/products/deletemultiple

编辑: 这个问题有一些很好的辩论:Restful way for deleting a bunch of items 它没有解决我关于使用 DELETE 请求的正文进行自定义删除操作的问题,但是关于批量删除的不同方式存在一些很好的争论。

【问题讨论】:

我肯定会选择您的第一个选项:DELETE /api/supplier/6/products 我同意,使用 DELETE 而不是 POST 我想知道我们是否可以发布 ID 列表。这确实有效,但可能不是正确的方法? 这个问题应该被关闭,因为它纯粹是基于意见的。 FWIW,停止查看 RFC 2616。它已经过时了。请改用 RFC 7231。不,这不会影响答案。 【参考方案1】:

我都做了,当我想将几个项目传递给删除操作时,我使用 POST 并且只使用 int[] 作为参数,但我确保我调用的 URL 非常明确的,因为我使用的是配置而不是约定:即:

/api/products/DeleteAllById

如果我要删除单个项目,那么我将使用DELETE

【讨论】:

这很有道理 是的,我们通过简单的 DELETE /api/products/5 删除单个项目我只是不确定是删除 /api/products (带有正文)还是 POST /api/product/deleteallbyid (有身体) 如果您已经在实施DELETE,我的投票将是POSTPOST 允许更大的请求,我相信。 如果这是一个不好的方法,请赐教。 这在一般概念上并不简单。好吧,实际上,这意味着需要将概念升级为多变的概念(CRUD,但在集合上)=)【参考方案2】:

首先,您应该将您的 ID 放在您的请求 URL 中,这样才能正常工作。

其次,在客户端批量处理您的请求(将其拆分为固定 id 计数的块)。 URL 的最大长度限制为 2000,因此,我建议将您的批次 ID 计数限制为 100 或类似的东西。这样您就可以获得最大的性能和最小的网络负载。

好吧,如果您想解决这个问题,而不是使用 REST 的概念和非常常见的批处理技术,只需使用 POST 即可,而不必担心批处理。实际上,它有一定的意义,因为 html 甚至不支持 DELETE =/ 它只是用一些框架(Ruby on Rails、javascript、AJAX 等)伪造的

【讨论】:

我不认为这是个好主意。 ID 的数量可能会有很大差异。首选选项是在请求正文中发送 ID 列表。 这是一种非常纯粹的方法(我非常喜欢),但是 UI 开发团队在使用 Ember Data 时必须创建批处理机制,我会遇到很多反对 更新了我的答案。 这到底是怎么回事,为什么每个人都投反对票甚至不提供建议? 哪些浏览器不支持DELETE?

以上是关于REST API 设计 - 使用请求正文删除多个项目的主要内容,如果未能解决你的问题,请参考以下文章

设计用于返回多个对象计数的 REST api

如何使用JSON正文在REST API POST方法中传递多个记录

SharePoint REST API 的 Expand 方法

REST API 设计:请求特定参数

如何使用 Scala 在具有请求正文的 REST API 上执行 GET 请求?

SharePoint REST API 的 Expand 方法