我正在构建一个 RESTful API 命令来停用用户记录。使用 DELETE 来执行此操作是否符合规定,或者应该将其作为 PUT,因为记录正在更新为“已停用”状态?还是只是口味问题?
DELETE
的语义意味着你实际上正在摆脱该对象。您在这里所做的似乎是对对象状态的修改。在这种情况下,PUT
或 PATCH
会更合适。
最好坚持您正在使用的统一接口的语义(在本例中为 HTTP 动词)。如果这些与您在应用程序中实际执行的操作相匹配,那么混乱就会减少。另外,如果您稍后决定
DELETE
应该实际删除一条记录,而不是仅仅将其标记为“非活动”,该怎么办?现在您已经更改了 API 的行为。另外,如果您使用 DELETE
,那么您本质上是遵循“最小意外原则”,这对于 API 来说是有好处的。最好让 DELETE
实际进行删除,而不是假装这样做。
另一方面,如果事实证明您需要保留数据用于历史目的,那么从一个位置删除记录并将其移动到其他位置(例如,从一个表到另一个表)是完全可以的。在这种情况下,该记录应该对未来的操作不可用(即资源上的
GET
应返回 404
)。
如果在停用操作之后,最终用户无法再通过“GET”访问该资源,除非再次重新激活该资源,那么使用“DELETE”我没有发现问题。否则,“PUT”更合适。
如果您发送
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"}
类似的事情用
PUT
或 PATCH
处理会更好:
GET /friends/bob => 200 OK {"status"="friend"}
PATCH /friends/bob {"status"="formerfriend"} => 204 No Content
GET /friends/bob => 200 OK {"status"="formerfriend"}
我不确定自该问题上次出现以来的 9 年多里情况是否发生了变化,但根据已接受的答案,当前阅读 DELETE 方法 表明时间已经发生变化:
DELETE 方法请求源服务器删除目标资源与其当前功能之间的关联。实际上,这种方法类似于UNIX中的“rm”命令:它表达的是对源服务器的URI映射的删除操作,而不是期望删除之前关联的信息。(强调我的)。
HTTP 请求方法是语义意图。 DELETE 的目的是删除 URI 和目标资源之间的关联(而不是按照接受的答案“实际上摆脱对象”)。
如果我收到 DELETE 请求,无论我如何删除该关联(实际上删除记录或将其标记为“非活动/已删除/无论什么”),GET 响应(最终满足意图)都不应该从请求的资源返回资源URI。它物理存在与否有什么关系吗?
根据当前规范,删除目标资源与其关联的 URI 映射之间的关联的任何操作都是 DELETE 方法的目的。