创建多个资源时,HTTP POST响应的Location头部信息是什么?

16

HTTP/1.1标准规定,如果POST操作导致创建资源,则响应应包括Location头部,其中包含新资源的地址。

如果在源服务器上创建了资源,则响应应为201(已创建),并包含描述请求状态和引用新资源的实体,以及Location头部(参见第14.30节)。

而在第14.30节中:

对于201(已创建)响应,Location是由请求创建的新资源的位置。

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

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

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

这个问题Http post response after multiple new resource creation?相似,但它询问的是响应实体,而不是头部(且未被回答)。

3个回答

8

RFC 2616已经过时了,除了历史目的外,请停止查看它。

当前的规范RFC 7231说:

"如果成功处理POST请求导致在源服务器上创建了一个或多个资源,则源服务器应发送一个包含Location头字段的201(已创建)响应,该字段提供创建的主要资源的标识符(第7.1.2节),并引用新资源的表示来描述请求的状态。" -- http://greenbytes.de/tech/webdav/rfc7231.html#POST

是的,当没有“主要”资源时,这并没有帮助太多。


1
正如你在我的例子中所看到的,没有“主要”资源 - 它们都是对等的。不确定在这种情况下该怎么办。 - metacubed
谢谢您提供新RFC的链接!我得为以后参考收藏一下。 - metacubed
我会保持这个问题开放一段时间,看看是否有其他建议。 - metacubed

7
我知道这个回答有些晚了,但我认为最好的解决方案是创建一个新的“Batches”资源,其中包含一个uuid标识符,可以使用以下URL返回已添加的书籍URL列表:
http://api.example.com/batches/{uuid}

e.g.

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

然后,您的 POSTPUT 可以在其 Location: {url} 标头上返回上述 URL 和一个 201 - Created 状态码。

如果您使用 GET 访问该 URL,则该资源应响应包含批处理中创建的 URL 列表以及有关批处理的任何其他信息(例如其 uuid 和创建时间/日期)的表示形式。

{
  "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"
  ]
}

这些资源可以设置为1小时或1个月的TTL,具体取决于您的选择。如果您希望,它们也可以永久存在;根据您的用例需求而定。


1
我认为软件应该签名以满足需求,而不是为了符合标准。对我来说,这表明标准存在差距。我认为返回URL,而不是创建的记录的ID规范是有意义的。然后在响应中添加ID数组。 - Mike de Klerk
@MikedeKlerk — 你能详细说明一下你所说的“我认为应该是‘signed’”是什么意思吗? - MikeSchinkel

3

我认为你在使用

Location 时有一个特殊的用例。在批量创建的情况下,处理结果通常在返回的内容本身中提供。实际上,处理可以完全或部分成功。我的意思是,所有元素都被添加或只有子集,并且结果向最终用户显示实际发生了什么。

因此,我认为在这种情况下不能使用

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,包括创建、更新和删除支持-有关更多详细信息,请参见此链接:http://www.elastic.co/guide/en/elasticsearch/guide/current/bulk.html
以下是类似的问题,可能会给出一些提示: 希望对您有所帮助, Thierry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接