可以使用 HTTP DELETE 停用记录吗?

Posted

技术标签:

【中文标题】可以使用 HTTP DELETE 停用记录吗?【英文标题】:Is it okay to use an HTTP DELETE to deactivate a record? 【发布时间】:2013-02-18 19:11:32 【问题描述】:

我正在构建一个 RESTful API 命令来停用用户记录。使用 DELETE 来执行此操作是否符合规定,或者这应该是 PUT,因为记录正在更新为“停用”状态?还是只是口味问题?

【问题讨论】:

【参考方案1】:

如果您发送DELETE 请求的URL 上的资源在该URI 上不再可用,则DELETE 是合适的。如果它仍然存在但改变了状态,那么它不是。

例如没关系(/friends/bob 中的资源消失了;在此过程中 /formerfriends/bob 中创建了一个新资源,但这是偶然的):

GET /friends/bob => 200 OK
GET /formerfriends/bob => 404 Not Found
DELETE /friends/bob => 204 No Content
GET /friends/bob => 410 Gone
GET /formerfriends/bob => 200 OK

这不是:

GET /friends/bob => 200 OK "status"="friend"
DELETE /friends/bob => 204 No Content
GET /friends/bob => 200 OK "status"="formerfriend"

使用PUTPATCH 会更好地处理类似的事情:

GET /friends/bob => 200 OK "status"="friend"
PATCH /friends/bob "status"="formerfriend" => 204 No Content
GET /friends/bob => 200 OK "status"="formerfriend"

【讨论】:

【参考方案2】:

DELETE 的语义意味着您实际上正在摆脱该对象。您在这里所做的似乎是对对象状态的修改。在这种情况下,PUTPATCH 会更合适。

最好坚持使用您正在使用的统一接口的语义(在本例中为 HTTP 动词)。如果这些与您在应用程序中实际执行的操作相匹配,那么混淆就会减少。此外,如果您稍后决定 DELETE 实际上应该删除一条记录,而不是仅仅将其标记为“非活动”,该怎么办?现在您已经更改了 API 的行为。此外,如果您使用DELETE,那么您实际上是在遵循“最少意外原则”,这对 API 很有用。最好让DELETE 实际删除,而不是假装这样做。

另一方面,如果事实证明您需要保留数据以用于历史目的,那么从一个位置删除记录并将其移动到其他位置(例如,从一个表到另一个表)是完全可以的。在这种情况下,该记录应该对未来的操作保持不可用(即,资源上的 GET 应该返回 404)。

【讨论】:

只是一个小补充:根据RFC-2616,服务器也可能将资源移动到无法访问的位置。最后,已删除资源上的 GET 应返回 404 @prehfeldt 正确!我在上一段中提到了这一点。添加了关于404 的部分以进一步澄清。 值得补充:如果您使用软删除技术,DELETE 仍然合适。 我同意@ChristoKiwi。许多应用程序不会物理删除数据库中的任何记录,而是将IsDeleted 列(或类似列)标记为1。所以国家历史的整个历史都被保留了。【参考方案3】:

如果在您的停用操作之后,最终用户无法再通过“GET”访问该资源,除非它再次被重新激活,我没有看到使用“DELETE”的问题。否则,“PUT”更合适。

【讨论】:

以上是关于可以使用 HTTP DELETE 停用记录吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用COM接口停用CanOe中的热点

在Web Api中实现Http方法(Get,Put,Post,Delete)

crm使用soap启用和停用记录

应该在表单中使用 PUT 和 DELETE 吗?

从GIT历史记录中删除文件

物联卡显示停用是怎么回事?物联网卡这些状态你都了解吗