在 wiki article for REST 中表明如果您使用 http://example.com/resources DELETE,这意味着您正在删除整个集合。
如果您使用 http://example.com/resources/7HOU57Y DELETE,则表示您正在删除该元素。
我正在做一个网站,注意不是网络服务。
我有一个列表,列表中的每个项目都有 1 个复选框。一旦我选择了多个要删除的项目,我将允许用户按下一个名为 DELETE SELECTION 的按钮。如果用户按下按钮,会弹出一个 js 对话框,要求用户确认删除。如果用户确认,则删除所有项目。
那么我应该如何以 RESTFUL 方式删除多个项目呢?
注意,目前对于网页中的 DELETE,我所做的是我使用 FORM 标记和 POST 作为操作,但包含一个自 this is what was indicated by others in SO on how to do RESTful delete for webpage 以来值为 DELETE 的 _method。
一种选择是创建删除“事务”。因此,您 POST
到 http://example.com/resources/deletes
一个新资源,其中包含要删除的资源列表。然后在您的应用程序中,您只需执行删除。当您发帖时,您应该返回您创建的交易的位置,例如 http://example.com/resources/deletes/DF4XY7
。对此的 GET
可以返回事务的状态(完成或正在进行)和/或要删除的资源列表。
我认为 rojoca's answer 是迄今为止最好的。一个轻微的变化可能是,取消同一页面上的 javascript 确认,而是创建选择并重定向到它,在该页面上显示确认消息。换句话说:
来自:
http://example.com/resources/
做一个
使用选择的 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 Ok(或任何适合成功删除的内容)
http://example.com/resources/selections/
之类的 uri 发送 DELETE 请求,并在请求的有效负载(正文)中发送要删除的项目的数据。据我所知,没有什么能阻止你这样做,但我总是遇到“但它不是 RESTfull”。
以下是 Amazon 使用他们的 S3 REST API 所做的事情。
个人删除请求:
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))
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 的一个示例。
个人删除请求:
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
批量请求:
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
有趣的是,我认为相同的方法适用于修补多个实体,并且需要考虑我们对 URL、参数和 REST 方法的含义。
返回所有“foo”元素:[GET] api/foo 返回“foo”元素,过滤特定 id:[GET] api/foo?ids=3,5,9
其中的意义是 URL 和过滤器确定“我们正在处理哪些元素?”,而 REST 方法(在本例中为“GET”)表示“如何处理这些元素?”
因此 PATCH 多个记录以将它们标记为已读 [PATCH] api/foo?ids=3,5,9
..数据 foo[read]=1
最后要删除多条记录,这个端点最符合逻辑:[DELETE] api/foo?ids=3,5,9
请理解我不相信这有任何“规则”——对我来说这只是“有意义”
我会说 DELETE http://example.com/resources/id1,id2,id3,id4 或 DELETE http://example.com/resources/id1+id2+id3+id4。由于“REST 是一种架构(...)[不是]协议”引用这篇维基百科文章,我相信没有单一的方法可以做到这一点。
我知道如果没有带有 HTML 的 JS,以上是不可能的,但我觉得 REST 是:
创建时不考虑交易等次要细节。谁需要对单个项目进行操作?这在 HTTP 协议中是合理的,因为它不打算通过它提供除静态网页之外的任何其他内容。
没有必要很好地适应当前模型 - 即使是纯 HTML。
正如 Decent Dabbler answer 和 rojocas answer 所说,最规范的是使用虚拟资源删除资源选择,但我认为从 REST 角度来看这是不正确的,因为执行 DELETE http://example.com/resources/selections/DF4XY7
应该删除选择资源本身,而不是选定的资源。
以 Maciej Piechotka anwser 或 fezfox answer 为例,我只有一个反对意见:有一种更规范的方式来传递一个 id 数组,并且使用数组运算符:
DELETE /api/resources?ids[]=1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d&ids[]=7e8f9a0b-1c2d-3e4f-5a6b-7c8d9e0f1a2b
通过这种方式,您正在攻击删除集合端点,但以正确的方式使用查询字符串过滤删除。
由于没有“正确”的方法来做到这一点,我过去所做的是:
在正文中使用 xml 或 json 编码数据将 DELETE 发送到 http://example.com/something。
当您收到请求时,检查 DELETE,如果为真,则阅读正文以查找要删除的内容。
A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.
来自 tools.ietf.org/html/rfc7231#section-4.3.5
我有同样的情况来删除多个项目。这就是我最终做的。我使用了 DELETE 操作,要删除的项目的 ID 是 HTTP 标头的一部分。