创建多个资源时,HTTP POST 响应位置 header

HTTP POST response Location header when creating multiple resources

HTTP/1.1 standard 声明如果 POST 操作导致创建资源,则响应应包含 Location header 以及资源的地址新资源。

If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30).

在第 14.30 节中,

For 201 (Created) responses, the Location is that of the new resource which was created by the request.

现在假设我的 API 允许通过 POST 将数组 collection 资源 URL 批量创建资源。例如:

POST /books
[
    {
        "name": "The Colour of Magic",
        "published": "1983"
    },
    {
        "name": "The Light Fantastic",
        "published": "1986"
    }
]

既然已经创建了两个\book\{bookId}资源,那么在这种情况下Locationheader的值应该是多少?

问题 类似,但它询问的是响应实体,而不是 header(并且未回答)。

RFC 2616 已过时。除非出于历史目的,否则请停止查看它。

当前规范 RFC 7231 说:

"If one or more resources has been created on the origin server as a result of successfully processing a POST request, the origin server SHOULD send a 201 (Created) response containing a Location header field that provides an identifier for the primary resource created (Section 7.1.2) and a representation that describes the status of the request while referring to the new resource(s)." -- http://greenbytes.de/tech/webdav/rfc7231.html#POST

是的,当没有 "primary" 资源时,这并没有多大帮助。

我认为您处于 header Location 的特定用例中。在批量创建的情况下,处理结果通常在返回的内容本身中提供。事实上,处理可以完全或部分成功。我的意思是添加了所有元素或仅添加了一个子集,结果向 end-user 显示了实际发生的情况。

所以我认为 header Location 在这种情况下不可用。我看到状态代码有两个选项:

  • 状态码为201如果至少创建了一个元素)
  • 状态码为200表示批量请求全局成功,但响应内容中描述了每次操作的结果。

但是,如果您的资源以异步方式处理批量创建,您会注意到状态代码 202 存在。但是在上下文中,您需要拉取资源以获取插入的状态。

关于回复的内容,您可以自由选择。我们可以想象这样的事情:

{
 "took": 4,
 "errors": true | false, 
 "items": [
  {  "added": true,
     "error": null
     "id": "123"
  },
  {  "added": false,
     "error": {
       "code": "err12",
       "description": "validation error (field type, ...)"
     }
     "id": null
  }
  ]
}

ElasticSearch 提供此类批量 api 创建以及更新和删除支持 - 请参阅此 link 了解更多详细信息:http://www.elastic.co/guide/en/elasticsearch/guide/current/bulk.html.

以下是可以提供一些提示的类似问题:

希望对你有帮助, 蒂埃里

我知道这个答案来晚了,但我相信最好的解决方案是创建一个新的 "Batches" 资源,其 uuid 标识符 return使用 URL 添加的图书列表 URL 如下:

http://api.example.com/batches/{uuid}

例如

http://api.example.com/batches/2b9b251f71a4b2901d66e04725bc0c9cb5843c74

那么你的POST或者PUT可以return上面的URL就可以了Location: {url} header还有一个201 - Created状态码。

如果您 GET 那个 URL 该资源应该以列出在该批次中创建的 URL 的表示形式响应,以及关于该批次的任何其他信息,例如作为它的 uuid 和它被创建的 time/date。

{
  "uuid": "2b9b251f71a4b2901d66e04725bc0c9cb5843c74",
  "datetime": "2005-08-15T15:52:01+00:00",
  "books": [
    "http://api.example.com/books/the-colour-of-magic",
    "http://api.example.com/books/the-light-fantastic"
  ]
}

这些资源可以有一个小时或一个月的 TTL,无论您选择什么。或者,如果你愿意,他们可以永远活着;无论您 use-case 需要什么。