【问题标题】:REST response - should I put the URL of the new resource in the header, body, or both?REST 响应 - 我应该将新资源的 URL 放在标头、正文还是两者中?
【发布时间】:2012-06-22 15:36:01
【问题描述】:

我已经组合了一个 API,它通过将新资源的内容放在响应正文中,并将新资源的 URL 放在 Location HTTP 响应标头中来响应 POST 请求。

示例请求:

POST /api/v1/widgets HTTP/1.1
Content-type: application/json;
Accept: application/json;

{
    "name": "hugo@example.com",
    "price": "10",
}

示例响应:

HTTP 201 Created
Location: http://example.com/api/v1/widgets/123456

{
    'widget': 
    {
        'id': "123456",
        'created': "2012-06-22T12:43:37+0100",
        'name': "hugo@example.com",
        'price': "10",
    },
}

有人提出了 URL 也应该在响应正文中的问题。有这方面的最佳做法吗?

【问题讨论】:

  • (如果过于主观,请随意删掉 - 不确定这是否违反 SO 的精神)

标签: http rest


【解决方案1】:

没有将新创建资源的位置(URL)放在正文中是有原因的:URL是服务消费者和服务之间消息交互所需的元数据,它不是“业务数据”。有一个名为"Messaging Metadata" 的 SOA 设计模式建议将 URL、安全凭证、相关标识符、事务 ID 和其他消息传递和组合上下文数据放在标题中,而不是放在消息的正文中。实际上,http 已经为此提供了标准标头 Location。

OTOH,如果您的 REST 服务使用 HATEOAS,则响应可能包含一个或多个 URL,这些 URL 是您希望为消费者提供动态绑定和调用的操作的直接链接。

我认为在标题和正文中都包含 URL 是最糟糕的解决方案。从长远来看,冗余数据容易出现不一致。

【讨论】:

    【解决方案2】:

    我会把它放在标题中(作为位置:http://blah.blah.com/blah)。如果你愿意,你也可以把它放在你的身体里(以你发送的任何适当的格式),这不会是不合适的。

    atompub REST API 通常是良好 REST API 的良好参考。他们把它放在两个里面。

    HTTP/1.1 201 Created
    Date: Fri, 7 Oct 2005 17:17:11 GMT
    Content-Length: nnn
    Content-Type: application/atom+xml;type=entry;charset="utf-8"
    Location: http://example.org/edit/first-post.atom
    ETag: "c180de84f991g8"  
    
    <?xml version="1.0"?>
    <entry xmlns="http://www.w3.org/2005/Atom">
      <title>Atom-Powered Robots Run Amok</title>
      <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
      <updated>2003-12-13T18:30:02Z</updated>
      <author><name>John Doe</name></author>
      <content>Some text.</content>
      <link rel="edit"
          href="http://example.org/edit/first-post.atom"/>
    </entry>
    

    【讨论】:

    • 感谢您的回复 - 拥有像 atompub 这样的基准正是我想要的。
    • 是的,但请注意,上面显示的从 AtomPub 返回的正文示例中的 URI 实际上是一个链接,它告诉接收者如果他们想要“编辑”资源(遵循 HATEOAS 原则)使用什么 URI )。严格来说,它不一定与资源本身的 URI 相同(即不一定与 Location: 标头中的值相同,它告诉您可以从哪里获取资源)。碰巧在这个例子中,获取资源的 URI 和用于编辑资源的 URI 是相同的。
    • 好的,很高兴知道。我原以为它们总是一样的。 OP 应该考虑到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 2020-12-24
    相关资源
    最近更新 更多