【问题标题】:Is it ok by REST to return content after POST?REST 是否可以在 POST 后返回内容?
【发布时间】:2010-12-22 05:46:10
【问题描述】:

我正在使用 RESTlet,并且我创建了一个资源。我通过覆盖 acceptRepresentation 方法来处理 POST。

客户端应该向我发送一些数据,然后我将其存储到 DB,将响应设置为 201 (SUCCESS_CREATED),我需要向客户端返回一些数据,但 acceptRepresentation 的返回类型是 void

就我而言,我需要返回一些标识符,以便客户端可以访问该资源。

例如,如果我有一个 URL 为 /resource 的资源并且客户端发送 POST 请求,我会在 DB 中添加一个新行,其地址应为 /resource/{id}。我需要发送{id}

我做错了吗? REST 原则是否允许在 POST 之后返回某些内容?如果是,我该怎么做,如果不是,处理这种情况的方法是什么?

【问题讨论】:

  • 查看 Thom 的回答,了解如何在 acceptRepresentation() 中设置响应正文。

标签: java rest restlet


【解决方案1】:

REST 只是说你应该遵守统一的接口。换句话说,它表示您应该按照HTTP spec 执行 POST 应该执行的操作。这是该规范中相关的引用,

如果已在 源服务器,响应应该 为 201(已创建)并包含一个实体 它描述了状态 请求并引用新的 资源和 Location 标头 (见第 14.30 节)。

从这里可以看出,您有两个地方可以向客户端指示新创建的资源所在的位置。 Location 标头应该有一个指向新资源的 URL,您也可以返回一个包含详细信息的实体。

我不确定重写 acceptRepresentation() 和重写 post() 之间有什么区别,但 this 示例显示了如何从 POST 返回响应。

【讨论】:

  • @del-boy:请参阅 Thom 的回答,了解如何在 acceptRepresentation() 中设置响应正文。
  • HTTP 规范引用不禁止响应,如果您查看第 6 节,则很清楚:允许:Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code. An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.
  • @MikeF 我无意推断不允许响应正文。我引用的规范部分专门说“并包含一个实体”。我的文字应该更清楚。
【解决方案2】:

我会放弃在响应正文中发送任何内容。只需将 Location: 设置为新创建资源的(完整)URL。

您的描述表明这正是您的语义:

  1. 发布一个东西来创建它
  2. 回答足够了解两件事:
    1. 创造发生了(201)
    2. 在哪里可以找到新事物(Location 标头)

其他都是多余的。

【讨论】:

  • 并不是说 Wikipedia 总是一个好的来源,但 that 还声称 "[...] 提供有关新创建资源位置的信息。在这种情况下,位置标头应使用 201 或 202 的 HTTP 状态代码发送。"
  • POST 可以执行创建一个或多个资源的逻辑。处理结果可能是客户需要的。因此,在响应中返回它可以避免对 API 进行一次或多次 GET 调用。 POST 方法创建/更改的数据可能不会(而且通常不会)对客户端来说是多余的。
【解决方案3】:

两个不同的问题:

REST 应用程序模式是否支持在 POST 中返回数据?

我不认为 REST 明确禁止它,但 Darrel 的回答中详细说明了首选的处理方法。

RESTlet 框架是否允许在 POST 中返回数据?

是的,即使它返回 void,在扩展 Resource 的类中,您也可以通过 getResponse() 方法完全访问 Response 对象对象。所以你可以用你想要的任何数据调用 getResponse().setEntity()。

【讨论】:

    【解决方案4】:

    以任何要求的格式输出。那可能是:

    <success>
        <id>5483</id>
    </success>
    

    或者:

    { "type": "success", "id": 5483 }
    

    这取决于你通常做什么。如果他们不期望数据,他们应该忽略它,但任何想要正确处理它的客户端都应该能够。

    【讨论】:

    • 好的,我有两种可能的格式(html 和 xml)。我知道如何处理请求格式的类型,但我不知道如何将数据添加到响应中。代表方法返回代表,所以我只返回我想要的,但是acceptRepresentation是无效方法,所以我不能返回任何数据......
    【解决方案5】:

    如果您使用实体主体而不是位置重定向来响应 201 Created,那么最好包含一个指向响应中表示的资源的 Content-Location 标头。

    这将避免潜在的混淆 - 客户端可以(有理由地)假设响应实体实际上代表“创建者”的新状态,而不是创建的资源。

    > POST /collection
    > ..new item..
    
    < 201 Created
    < Location: /collection/1354
    < Content-Location: /collection/1354
    < <div class="item">This is the new item that was created</div>
    

    【讨论】:

    • 我认为 Content-Location 的目的不同。 HTTP 规范说没有为 POST 和 PUT 定义 Content-Location。 Location 标头与 201-Create 一起使用。返回位置不会自动进行重定向,您需要一个 3XX 响应代码。
    • 位置标头用于(在 201 响应中)指示创建的资源所在的位置;它与其随附的响应的实体正文无关。我的观点是 - 如果您想在 201 响应本身中包含创建的资源(而不是将客户端定向/重定向到另一个 URI),那么内容位置标头将是一个好主意。这可能有点“改变规则”,但它比需要另一个请求/响应周期来获取新资源的状态给客户端更有效。
    • 对我有意义。我以前从未使用过 Content-Location 标头。
    • 如果客户端是使用浏览器的人,则返回 201 和 Location 标头是没有意义的。用户将不知道如何处理它。如果客户端是机器人,它可以通过编程知道如何处理它 - 就像对位置的跟进 GET。
    • @irreputable:我相信 REST 是用来设计 API 的,其中 A 不代表寻找一些 HTML 来呈现的用户代理。
    猜你喜欢
    • 1970-01-01
    • 2011-08-10
    • 2023-01-13
    • 2011-03-04
    • 2018-10-06
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    相关资源
    最近更新 更多