使用HTTP DELETE来停用记录是否可行?

22
我正在构建一个RESTful API命令来停用用户记录。使用DELETE命令是否合适,还是应该使用PUT命令,因为记录被更新为“已停用”状态?或者这只是一种口味问题?
3个回答

20
“DELETE” 的语义意味着您实际上正在摆脱该对象。在这种情况下,您所做的似乎是修改对象的状态。在这种情况下,使用“PUT”或“PATCH”更为合适。
最好坚持您正在使用的统一接口的语义(在本例中为HTTP动词)。如果它们与您在应用程序内部实际执行的操作相匹配,则会减少混淆。此外,如果您稍后决定“DELETE”实际上应删除记录而不仅仅是将其标记为“非活动”,那么您已更改API的行为。另外,如果您使用“DELETE”,则基本上遵循“最小惊讶原则”,这对于API来说是有益的。最好让“DELETE”实际上执行删除操作,而不是只是假装这样做。
另一方面,如果发现需要出于历史目的保留数据,则从一个位置删除记录并将其移动到另一个位置(例如,从一个表移动到另一个表)是完全可以的。在这种情况下,该记录应该保持不可用以进行未来的操作(即,对资源的“GET”应返回“404”)。

1
只是一个小的补充:根据RFC-2616,服务器也可以将资源移动到无法访问的位置。最后,对已删除资源的GET应返回404 - prehfeldt
@prehfeldt 正确!我在最后一段提到了这一点。为了进一步澄清,我添加了关于 404 的说明。 - Vivin Paliath
3
值得补充的是:如果您使用软删除删除技术,则DELETE仍然是适当的。 - ChristoKiwi
2
我同意@ChristoKiwi的观点。许多应用程序在数据库中并不会物理删除任何记录,而是将“IsDeleted”列(或类似列)标记为“1”。因此,整个状态历史记录都被保留下来。 - themefield

8
如果在您执行停用操作后,资源不能通过“GET”再次被最终用户访问,除非它被重新激活,那么我认为使用“DELETE”没有问题。否则,“PUT”更加合适。

5

如果您发出的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"}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接