首页 > 解决方案 > 如果端点既删除资源又创建资源,它仍然是惯用的 POST 吗?

问题描述

我一直在尽最大努力编写 RESTful API 端点,最近遇到了一个我不知道如何处理的场景。我创建了一个模型,该模型具有有效性时间限制和一个端点,该端点应该:

  1. 如果资源不存在,则为用户创建资源,或者
  2. 删除旧资源,如果它确实存在并且已过期,则创建一个新资源

我当前的实现是一个在资源创建期间处理此逻辑的端点,但是在 POST 请求期间同时进行删除和创建的一些事情感觉不对。发出多个请求来处理同一个任务也感觉不对,因为如果用户最终获得两个资源,或者如果创建请求失败、删除请求和请求请求过于冗长,这似乎会引入错误的可能性再次创作。解决此问题的惯用且稳健的方法是什么?

标签: javascriptresthttppostdjango-rest-framework

解决方案


首先回答标题问题,POST 行为的删除部分不是惯用的,因为 POST 通常不用于替换,但我不认为这是严格禁止的,所以根据您的情况(如下所述),POST 或 PUT都是可以接受的方法。

当您的案例应该使用 PUT 时:

如果您知道 ID,那么最好的办法是:

PUT /your/resource/path/<id>

原因: POST严格地用于创建资源。在我看来,PUT 更多地用于您想要“创建或替换”的情况,这与您的要求一样接近。

这是一个很好的来源,可以讨论并支持我所说的:

REST 中的 PUT 与 POST

和一个很好的摘录:

PUT 方法请求将封闭的实体存储在提供的 Request-URI 下。如果 Request-URI 引用了一个已经存在的资源,封闭的实体应该被认为是在源服务器上的一个修改版本。如果 Request-URI 不指向现有资源,并且该 URI 能够被请求用户代理定义为新资源,则源服务器可以使用该 URI 创建资源。”

当您的案例应该使用 POST 时:

如果您的 ID 是在后端生成的和/或您不知道如何在创建时识别资源,那么出于所有相关目的,就您对 REST 的使用而言,您正在创建一个新资源,因此您应该使用 POST。您最终可能会遇到一些古怪的后端行为,有些人会争辩说这违反了 REST,但在这种情况下,除了从核心重新考虑您的解决方案之外,没有更好的选择。

最后注:

如果您在创建时不知道 ID,那么您甚至不能退回到 DELETE → (re)POST,因为要删除,您应该按 ID 定位。如果您在没有 ID 的情况下删除,那么您还有其他“这是惯用的”问题要回答。


推荐阅读