关于休息:删除一堆项目的宁静方式

Restful way for deleting a bunch of items

在REST的wiki文章中
表示如果您使用http://example.com/resources DELETE,则表示您正在删除整个集合。

如果您使用http://example.com/resources/7HOU57Y DELETE,则表示您正在删除该元素。

我正在做一个网站,请注意不要WEB服务。

我有一个列表,列表中的每个项目都有1个复选框。 一旦我选择了多个要删除的项目,我将允许用户按下名为DELETE SELECTION的按钮。 如果用户按下按钮,将弹出一个js对话框,要求用户确认删除。 如果用户确认,则删除所有项目。

那么我该如何迎合以RESTFUL方式删除多个项目?

注意,目前对于网页中的DELETE,我所做的是使用带有POST作为操作的FORM标签,但是包含值为DELETE的_method,因为这是其他人在SO中关于如何对网页进行RESTful删除的指示。


一种选择是创建删除"事务"。所以POST就像http://example.com/resources/deletes这样的新资源,包含要删除的资源列表。然后在您的应用程序中,您只需删除。当您发布帖子时,您应该返回您创建的交易的位置,例如http://example.com/resources/deletes/DF4XY7。此处的GET可以返回事务的状态(完成或正在进行)和/或要删除的资源列表。


我认为rojoca的答案是迄今为止最好的。稍微变化可能是,在同一页面上取消javascript确认,而是创建选择并重定向到它,在该页面上显示确认消息。换一种说法:

从:
http://example.com/resources/

做一个

POST选择ID以:
http://example.com/resources/selections

如果成功,应该回复:

已创建HTTP / 1.1 201,并且Location头位于:
http://example.com/resources/selections/DF4XY7

在此页面上,您将看到一个(javascript)确认框,如果您确认将执行以下请求:

删除http://example.com/resources/selections/DF4XY7

如果成功,应该回复:
HTTP / 1.1 200好(或任何适合成功删除的内容)


以下是亚马逊使用他们的S3 REST API所做的事情。

个人删除请求:

1
2
3
4
5
DELETE /ObjectName HTTP/1.1
Host: BucketName.s3.amazonaws.com
Date: date
Content-Length: length
Authorization: authorization string (see Authenticating Requests (AWS Signature Version 4))

多对象删除请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /?delete HTTP/1.1
Host: bucketname.s3.amazonaws.com
Authorization: authorization string
Content-Length: Size
Content-MD5: MD5

<?xml version="1.0" encoding="UTF-8"?>
<Delete>
    <Quiet>true</Quiet>
    <Object>
         <Key>Key</Key>
         <VersionId>VersionId</VersionId>
    </Object>
    <Object>
         <Key>Key</Key>
    </Object>
    ...
</Delete>

但Facebook Graph API,Parse Server REST API和Google Drive REST API甚至可以让您在一个请求中"批量"执行单个操作。

这是Parse Server的一个例子。

个人删除请求:

1
2
3
4
curl -X DELETE \
  -H"X-Parse-Application-Id: ${APPLICATION_ID}" \
  -H"X-Parse-REST-API-Key: ${REST_API_KEY}" \
  https://api.parse.com/1/classes/GameScore/Ed1nuqPvcm

批量请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
curl -X POST \
  -H"X-Parse-Application-Id: ${APPLICATION_ID}" \
  -H"X-Parse-REST-API-Key: ${REST_API_KEY}" \
  -H"Content-Type: application/json" \
  -d '{
       "requests": [
          {
           "method":"POST",
           "path":"/1/classes/GameScore",
           "body": {
             "score": 1337,
             "playerName":"Sean Plott"
            }
          },
          {
           "method":"POST",
           "path":"/1/classes/GameScore",
           "body": {
             "score": 1338,
             "playerName":"ZeroCool"
            }
          }
        ]
      }' \
  https://api.parse.com/1/batch

我会说DELETE http://example.com/resources/id1,id2,id3,id4或DELETE http://example.com/resources/id1+id2+id3+id4。正如"REST是一种架构(...)[非]协议"引用这篇维基百科文章,我相信,没有一种方法可以做到这一点。

我知道如果没有带HTML的JS,上面是不可能的,但我觉得REST是:

  • 创建时没有考虑像交易这样的小细节。谁需要操作更多单品?这在HTTP协议中是合理的,因为除了静态网页之外,它不打算通过它提供任何其他服务。
  • 没有必要很好地适应当前的模型 - 即使是纯HTML。


有趣的是,我认为相同的方法适用于PATCHing多个实体,并且需要考虑我们对URL,参数和REST方法的含义。

  • 返回所有'foo'元素:

    [GET] api/foo

  • 返回'foo'元素,过滤特定ID:

    [GET] api/foo?ids=3,5,9

  • 其中感觉是URL,过滤器确定"我们正在处理什么元素?",REST方法(在本例中为"GET")说"如何处理这些元素?"

  • 因此,PATCH多个记录将它们标记为已读

    <5233>

  • ..与数据foo [读取] = 1

  • 最后要删除多条记录,这个端点最合乎逻辑:

    [DELETE] api/foo?ids=3,5,9

  • 请理解我不相信对此有任何"规则" - 对我来说它只是"有意义"


    正如Decent Dabbler的回答和rojocas的回答所说,最规范的是使用虚拟资源来删除一系列资源,但我认为从REST的角度看这是不正确的,因为执行DELETE http://example.com/resources/selections/DF4XY7应该删除选择资源本身,而不是选中资源。

    以Maciej Piechotka anwser或fezfox的答案为例,我只有一个反对意见:有一种更规范的方法来传递一组id,并使用数组运算符:

    DELETE /api/resources?ids[]=1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d&ids[]=7e8f9a0b-1c2d-3e4f-5a6b-7c8d9e0f1a2b

    通过这种方式,您将攻击Delete Collection端点,但以正确的方式使用查询字符串过滤删除。


    我有同样的情况删除多个项目。 这就是我最终做的事情。 我使用DELETE操作,要删除的项目的ID是HTTP标头的一部分。


    由于没有"正确"的方法来做到这一点,我过去所做的是:

    使用正文中的xml或json编码数据将DELETE发送到http://example.com/something。

    当您收到请求时,检查DELETE,如果为true,则读取正文以查找要删除的请求。