删除多个项目的REST方式是什么?
我的用例是,我有一个 Backbone.js 集合,其中我需要能够删除多个项目一次。选项似乎是:
1.为每个记录发送DELETE请求(如果可能有几十个项目,这似乎是个坏主意);
1.发送DELETE,其中要删除的ID在URL中串在一起(即,“/records/1; 2.3英寸);
1.以非REST方式发送一个自定义JSON对象,该对象包含标记为删除的ID。
所有的选择都不太理想。
这看起来像是REST约定的灰色区域。
删除多个项目的REST方式是什么?
我的用例是,我有一个 Backbone.js 集合,其中我需要能够删除多个项目一次。选项似乎是:
1.为每个记录发送DELETE请求(如果可能有几十个项目,这似乎是个坏主意);
1.发送DELETE,其中要删除的ID在URL中串在一起(即,“/records/1; 2.3英寸);
1.以非REST方式发送一个自定义JSON对象,该对象包含标记为删除的ID。
所有的选择都不太理想。
这看起来像是REST约定的灰色区域。
6条答案
按热度按时间luaexgnf1#
1.是一个可行的REST式选择,但显然具有您所描述的局限性。
1.不要这样做。它会被中介解释为意味着“删除
/records/1;2;3
处的(单个)资源“--所以对此的2xx响应可能会导致它们清除/records/1;2;3
的缓存;不吹扫/records/1
、/records/2
或/records/3
;代理/records/1;2;3
的410响应,或者其他从您的Angular 看没有意义的事情。1.如果您想创建一个API,并且希望允许对资源进行大量更改,您可以使用REST来实现这一点,但是对于许多人来说,具体的方法并不是显而易见的。一种方法是创建一个“更改请求”资源(例如,通过将诸如
records=[1,2,3]
的主体POST到/delete-requests
),并轮询所创建的资源(由响应的Location
头指定)来确定您的请求是否已被接受、拒绝正在进行或已完成。这对于长时间运行的操作很有用。另一种方法是向列表资源发送PATCH
请求,/records
,其主体包含资源和要对这些资源执行的操作的列表(采用您希望支持的任何格式)。这对于请求的响应代码可以指示操作结果的快速操作非常有用。在保持REST约束的同时,可以实现任何事情,通常的答案是将“问题”变成一个资源,并给予一个URL。
因此,批处理操作,例如在此处删除、将多个项目发布到列表中、或者对大量资源进行相同的编辑,都可以通过创建一个“批处理操作”列表并将新操作发布到该列表中来处理。
不要忘记,REST并不是解决任何问题的唯一方法。“REST”只是一种架构风格,您并不 * 必须 * 遵循它(但是如果你不这样做的话,你会失去互联网的某些好处)我建议你看看这个HTTP API architectures的列表,然后选择一个适合你的。只要让你自己意识到如果你选择另一个架构,你会失去什么。并根据您的用例做出明智的决策。
在Patterns for handling batch operations in REST web services?上有一些关于这个问题的糟糕答案,它们有太多的赞成票,但也应该读一读。
70gysomp2#
如果
GET /records?filteringCriteria
返回匹配条件的所有记录的数组,则DELETE /records?filteringCriteria
可以删除所有这样的记录。在这种情况下,您的问题的答案将是
DELETE /records?id=1&id=2&id=3
。egmofgnx3#
我认为Mozilla存储服务SyncStorage API v1.5是使用REST删除多个记录的好方法。
删除整个集合。
使用单个请求从集合中删除多个BSO。
ids*:从集合中删除其ID在提供的逗号分隔列表中的BSO。最多可以提供100个ID。*
删除指定位置的BSO。
http://moz-services-docs.readthedocs.io/en/latest/storage/apis-1.5.html#api-instructions
rfbsl7qr4#
这看起来像是REST约定的灰色区域。
是的,到目前为止,我只看到过一个提到批处理操作(如批处理删除)的REST API设计指南:google api design guide的关系。
本指南mentions介绍了“自定义”方法的创建,这些方法可以通过使用冒号的资源进行关联,例如
https://service.name/v1/some/resource/name:customVerb
,它还明确提到了批处理操作作为用例:自定义方法可以与资源、集合或服务相关联。它可以接受任意请求并返回任意响应,还支持流请求和响应。[...]自定义方法应使用HTTP POST predicate ,因为它具有最灵活的语义[...]对于性能关键的方法,提供自定义批处理方法以减少每个请求的开销可能会很有用**。
因此,你可以根据google的api指南做以下事情:
...删除收藏资源中的一组项目。
5lhxktic5#
我允许对集合进行大规模替换,例如
PUT ~/people/123/shoes
,其中主体是整个集合的表示形式。这适用于小的项目子集合,客户端希望查看项目并删除一些项目,然后添加一些项目,然后更新服务器。他们可以PUT一个空集合来删除所有项目。
这意味着即使PUT删除了
GET ~/people/123/shoes/9
,它仍然会保留在缓存中,但这只是一个缓存问题,如果其他人删除了shoe,这将是一个问题。我的数据/系统API总是使用ETag,而不是过期时间,这样服务器在每次请求时都会被命中,我需要正确的版本/并发头来改变数据。对于只读和视图/报告对齐的API,我确实使用过期时间来减少对源的命中,例如,排行榜可以在10分钟内有效。
对于更大的集合,比如
~/people
,我倾向于不需要多次删除,用例倾向于不自然出现,所以单个DELETE工作得很好。在将来,根据构建REST API的经验和遇到相同问题和需求(如审计)的经验,我倾向于只使用GET和POST predicate ,并围绕事件进行设计,例如POST地址更改事件,尽管我怀疑这会带来一系列问题:)
我还允许前端开发人员构建他们自己的API,这些API使用更严格的后端API,因为他们不喜欢严格的“字段狂热者”REST API设计通常有实际的、有效的客户端原因,以及出于生产力和缓存分层的原因。
mi7gmzs66#
您可以POST一个已删除的资源:). URL将是
POST /deleted-records
,主体将是{"ids": [1, 2, 3]}