RESTful 相关资源受影响时的响应方式

RESTful way to respond when related resource is affected

假设有一个名为 Draft '/api/drafts/' 的资源和另一个名为 Revision '/api/revisions/' 的资源。它们是一对一的关系。

要创建修订版,您在“/api/revisions/”上发出请求 POST 并在参数中提供草稿 ID。 JSON API 这样做的方式意味着

POST /api/revisions/
Content-type: application/json

{
    "data": {
        "type": "revision",
        "links": {
            "draft": { "linkage": { "id": 1, "type": "draft" } }
        }
    }
}

这将创建修订资源并且它与 Draft id=1 相关。所以响应如下:

201 Created
Content-type: application/json
{
    "data": {
        "id": 1,
        "type": "revision",
        "links": {
            "draft": { "linkage": { "id": 1, "type": "draft" } }
        }
    }
}

但是,POST /api/revisions/ 有一个副作用;它改变了草稿的属性。

例如) draft.revision_count: 0 => 1

然而,客户端所做的只是请求创建修订并因此收到创建的修订资源,无法知道草稿数据是否已更改。

我的问题是,服务器是否负责让客户端知道通过创建修订其他资源会受到影响并需要更新?

服务器不应在 POST /api/revisions 的响应中告诉客户端 草稿 已更改。

但是客户端不应该期望它知道的草稿的客户端状态仍然有效。它应该提出一个请求

GET /api/drafts/1
If-None-Match: "etag-of-this-draft-the-server-returned-last-time"

If-None-Match 的值将是 ETag 服务器 return 在客户端先前对此资源做出的响应中编辑的值。如果草稿的服务器状态已更改,则 ETag 不会 macth,客户端将 return 草稿的 new 状态。如果草稿的服务器状态没有改变,服务器将响应 304.

如果客户端不能确保它知道的状态与当前服务器状态匹配,当客户端试图通过例如在草稿上制作 PUT 来更改草稿时,可能会发生冲突。如果它在 PUT 请求中包含 If-None-Match header,服务器将能够检测到当前服务器状态与过时的客户端状态之间的任何不匹配。它可以使用正确的 HTTP 状态代码进行响应。