【问题标题】:Responding to an idempotent HTTP POST request响应幂等 HTTP POST 请求
【发布时间】:2010-08-11 12:19:35
【问题描述】:

我们的部分 RESTful API 将允许用户使用序列号注册商品。由于序列号不是全局唯一的,它不能用作资源的标识符,所以我们将使用 POST 到将生成标识符的父资源,例如

POST /my/items

<item serial-number="ABCDEF" />

在项目尚未注册的情况下,HTTP 语义定义良好。我们返回一个 Location 头,并将注册的项目作为实体主体,例如

HTTP 201 Created
Location: /my/items/1234    

<item id="1234" serial-number="ABCDEF" />

但是,在项目已经注册的情况下,API 应该是幂等的,并且返回之前注册的项目而不创建新项目。我最好的猜测是它应该返回一个 200 OK 状态码,并使用 Content-Location 标头来指示项目实际来自哪里,例如

HTTP 200 OK
Content-Location: /my/items/1234    

<item id="1234" serial-number="ABCDEF" />

这看起来合理吗?我不完全清楚 Location 或 Content-Location 是否更适合第二种情况。

【问题讨论】:

    标签: http rest http-post


    【解决方案1】:

    我最近有类似的要求。对于幂等操作,PUT 是最好的方法。你是对的,外部ID和内部ID不匹配。我通过为外部 id 目标创建专用资源来解决它:

    PUT /api-user/{username}/items/{serialNumber}
    

    如果我没有“用户名”和“ABCDEF”序列号的项目,我会在内部将其解析为 CREATE,如果有,则将其解析为 UPDATE。

    如果它是 CREATE,我返回 201 以获得 UPDATE 200。此外,返回的有效负载包含本地 id 和外部序列号,就像您在有效负载中建议的那样。

    【讨论】:

    • 嗯,是的,其实我喜欢这个。尽管序列号可能不是全球唯一的,但几乎 100% 的概率它们在用户范围内是唯一的,因此它可以充当范围唯一标识符。它还可以解决我的问题,即设备如何通过在此 URL 上使用 GET 并检查响应是 200 还是 404 来检查它是否已经注册。谢谢!
    【解决方案2】:

    Here 是关于这两个标头用法的有趣讨论。它声称 Content-Location 没有为 PUT 或 POST 定义,因此 Location 在您的情况下可能是更好的选择。当然,这不是明确的,但哪个更好。

    总的来说,我认为你的方法是有道理的。

    【讨论】:

    • 那篇文章说没有为 PUT 和 POST 定义 Content-Location,HTTP 规范实际上说它没有为请求定义,但没有说明任何关于回应。我认为说 Content-Location 用于替代形式可能是正确的,而 Location 是实际位置。从规范很难确定:-S
    猜你喜欢
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    相关资源
    最近更新 更多