使用REST删除多个记录

Don*_*lor 80 api rest backbone.js

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

我的用例是我有一个Backbone Collection,我需要能够一次删除多个项目.选项似乎是:

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

所有选项都不太理想.

这似乎是REST约定的灰色区域.

Nic*_*nks 74

  1. 是一个可行的RESTful选择,但显然有你所描述的限制.
  2. 不要这样做.中介机构将其解释为"删除(单个)资源/records/1;2;3" - 因此对此的2xx响应可能会导致它们清除其缓存/records/1;2;3; 吹扫/records/1,/records/2/records/3; 代理410响应/records/1;2;3,或其他从您的观点来看没有意义的事情.
  3. 这个选择是最好的,可以RESTful完成.如果您正在创建API并且希望允许对资源进行大量更改,则可以使用REST来执行此操作,但确切地说,对于许多人来说,这并不是很明显.一种方法是创建一个"变更请求"的资源(例如,通过发布一个体如records=[1,2,3]/delete-requests)和轮询创建的资源(由指定Location的响应报头),以找出是否您的申请已被接受,拒绝,正在进行中或已完成.这对于长时间运行的操作很有用.另一种方式是发送PATCH到列表中的资源请求,/records,体内都包含资源和行动的清单,对这些资源进行(在你想支持任何格式).这对于快速操作很有用,其中请求的响应代码可以指示操作的结果.

在保持REST限制的同时,一切都可以实现,通常答案是将"问题"变成资源,并给它一个URL.
因此,批处理操作(例如在此处删除,或将多个项目发布到列表中,或对大量资源进行相同的编辑)都可以通过创建"批处理操作"列表并将新操作发布到它来处理.

不要忘记,REST不是解决任何问题的唯一方法."REST"只是一种建筑风格,你不具备坚持它(但你失去了上网的一些好处,如果你不这样做).我建议你查看这个HTTP API架构列表,然后选择适合你的那个.如果您选择其他架构,只要让自己意识到自己失去了什么,并根据您的用例做出明智的决定.

对于处理REST Web服务中的批处理操作的模式,这个问题有一些不好的答案有太多的赞成,但也应该被阅读.

  • 您需要担心的不是您的服务器,而是中介、CDN、缓存代理等。互联网是一个分层系统。这就是*原因*它运作良好。Roy 确定系统的哪些方面是其成功所必需的,并将它们命名为 REST。如果您发出`DELETE` 请求,则请求者和服务器之间的任何内容都会认为指定 URL 上的单个资源正在被删除。查询字符串是这些设备的 URL 的不透明部分,因此您如何指定 API 无关紧要,它们不知道这些知识,因此不会有不同的行为。 (3认同)
  • 如果由于URI长度限制而需要删除大量资源,则/ records / 1; 2; 3将不起作用 (3认同)
  • 请注意,如果考虑DELETE和定义要清除的资源的主体,那么某些中介可能无法转发正文.此外,某些HTTP客户端无法将正文添加到DELETE.请参阅http://stackoverflow.com/questions/299628/is-an-entity-body-allowed-for-an-http-delete-request (3认同)
  • #3参数的问题在于它与#2的反驳参数相同.创建to-delete资源不是上游代理知道如何处理的东西 - 与方法#2相同的计数器参数. (3认同)
  • @LukePuplett我只是简单地说,禁止将带有“ DELETE”请求的请求正文传递。不要这样 如果你愿意,我会吃掉你的孩子。nom nom nom。 (2认同)

Mar*_*ila 16

如果GET /records?filteringCriteria返回与条件匹配的所有记录的数组,则DELETE /records?filteringCriteria可以删除所有此类记录.

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

  • `GET/records?id = 1&id = 2&id = 3`does*not*mean"获取ID为1,2和3的三条记录",这意味着"获取具有URL路径/记录的单一资源?id = 1&id = 2&id = 3"这可能是萝卜的图片,是一个包含中文数字"42"的纯文本文件,或者可能不存在. (7认同)
  • @NicholasShanks我真的不同意.如果结果被缓存,那就是服务器的错误.如果您正在讨论API的设计,那么您希望是为服务器编写代码的人.无论您在查询字符串中使用`id [] = 1&id [] = 2`或`id = 1&id = 2`来表示值数组,该查询字符串都表示这一点.我认为让查询字符串代表过滤器是非常普遍和好的做法.此外,**如果允许删除和更新,请不要缓存`GET`请求.**如果这样做,客户端将保持陈旧状态. (3认同)
  • 我也得出了这样的结论:只要将动词翻转到你想做的事情即可。我不明白为什么适用于 GET 的内容不适用于 DELETE。 (2认同)

boo*_*oon 14

我认为 Mozilla Storage Service SyncStorage API v1.5 是使用 REST 删除多个记录的好方法。

删除整个集合。

DELETE https://<endpoint-url>/storage/<collection>
Run Code Online (Sandbox Code Playgroud)

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

DELETE https://<endpoint-url>/storage/<collection>?ids=<ids>
Run Code Online (Sandbox Code Playgroud)

ids:从集合中删除其 id 在提供的逗号分隔列表中的 BSO。最多可提供 100 个 ID。

删除给定位置的 BSO。

DELETE https://<endpoint-url>/storage/<collection>/<id>
Run Code Online (Sandbox Code Playgroud)

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

  • 这*似乎*是一个很好的解决方案。我想如果mozilla认为它是正确的那么它一定是正确的?唯一的问题是错误处理。假设他们传递 ?ids=1,2,3 并且 id 3 不存在,您是否删除 1 和 2,然后用 200 响应,因为请求者希望 3 消失,但它不存在,所以这并不重要?或者如果他们被授权删除 1 但不能删除 2 该怎么办...您是否什么都不删除并以错误响应,或者您是否删除您可以删除的内容并保留其他内容... (2认同)
  • 我通常会返回成功的响应,因为无论如何最终状态都是相同的。这也简化了客户端的逻辑,因为它们不再需要处理该错误状态。至于授权案例,我只会使整个请求失败......但这实际上取决于您的用例。 (2认同)

B12*_*ter 5

这似乎是 REST 约定的灰色区域。

是的,到目前为止,我只遇到过一个提到批量操作(例如批量删除)的 REST API 设计指南:google api 设计指南

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

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

因此,您可以根据 google 的 api 指南执行以下操作:

POST /api/path/to/your/collection:batchDelete
Run Code Online (Sandbox Code Playgroud)

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