按照惯例应该返回哪些 REST PUT/POST/DELETE 调用?

Posted

技术标签:

【中文标题】按照惯例应该返回哪些 REST PUT/POST/DELETE 调用?【英文标题】:What REST PUT/POST/DELETE calls should return by a convention? 【发布时间】:2010-11-24 15:52:32 【问题描述】:

    根据“REST 意识形态”,PUT/POST/DELETE 请求的响应正文中应该包含什么内容?

    返回码呢? HTTP_OK够了吗?

    这些约定的原因是什么?

我找到了一篇描述 POST/PUT 差异的好帖子:POST vs PUT 但它仍然没有回答我的问题。

【问题讨论】:

【参考方案1】:

请原谅我的轻率,但如果您通过 HTTP 执行 REST,那么 RFC7231 会准确描述 GET、PUT、POST 和 DELETE 的预期行为。

更新(2014 年 7 月 3 日): HTTP 规范有意不定义从 POST 或 DELETE 返回的内容。规范只定义了需要定义的内容。其余的留给实施者选择。

【讨论】:

@tuxslayer 我很高兴你不认为我只是想变得刻薄。许多人似乎认为 REST 在 HTTP 方法之上添加了额外的要求。然而,事实并非如此。还有一些额外的限制,但它们并不会真正影响 HTTP 方法的行为。 RFC2616 绝对是要遵循的指南。 我很欣赏这个链接。 :) 这让我停下来思考我正在使用的工具。在阅读了你的帖子和 RFC 之后,我发现自己在晚上剩下的时间里都在提到 RFC。它帮助我首先将进程视为 HTTP 进程,然后将其视为休息进程。非常感谢。 @PerryTew 现在您可以前往tools.ietf.org/wg/httpbis 并查看当前正在修订的 HTTP 规范版本。享受吧! 也许我只是需要更多的睡眠,但我似乎无法在 RFC 中找到 OP 要求的确切信息。 POST 或 DELETE 响应的正文应该是什么? 嗯,这就像泥巴一样清晰。也许答案中的更多信息会有所帮助。尤其是当该链接失效时。【参考方案2】:

总体而言,这些约定是“认为您只是在交付网页”。

对于 PUT,如果您在之后立即执行 GET,我会返回相同的视图;这将导致 200(当然,假设渲染成功)。对于 POST,我会重定向到创建的资源(假设您正在执行创建操作;如果没有,则只返回结果);成功创建的代码是 201,它实际上是唯一一个不在 300 范围内的重定向 HTTP 代码。

我从来没有对 DELETE 应该返回什么感到高兴(在这种情况下,我的代码当前会生成 HTTP 204 和空正文)。

【讨论】:

PUT 请求返回下一页似乎是一种不好的做法,因为在结果页面上刷新会导致请求再次执行。相反,对我来说,假设您正在处理同步请求,则进行重定向是有意义的。 @lobati 我认为重要的是要注意发送多个相同的 PUT 请求,应该与只发送一个相同的 PUT 请求具有完全相同的结果。鉴于上述情况,您提出的问题现在可能不那么重要了? @Iain 不是真的。问题是,如果以后有其他东西更新了记录,您不希望它发送另一个 PUT 请求导致数据被还原。例如,如果两个人引用同一个页面,一个更新,然后另一个更新,如果第一个人刷新查看结果,实际上最终会导致事情恢复到第二个人之前他们的变化。 “像网站一样思考”是完美的,因此删除可能会响应一些可能的下一步操作,这取决于您为什么要删除资源的“故事”。这至少可以是一个链接,可以将代理带回某个逻辑的操作起始位置,甚至可以重定向到显示删除影响(订单总数)并包含更多链接的状态资源。【参考方案3】:

创建资源通常映射到 POST,并且应该返回新资源的位置;例如,在 Rails 脚手架中,CREATE 将重定向到新创建资源的 SHOW。同样的方法可能对更新(PUT)有意义,但这不是惯例;更新只需要表明成功。删除可能也只需要表明成功;如果你想重定向,返回资源列表可能是最有意义的。

HTTP_OK表示成功,是的。

我上面所说的唯一一成不变的规则是 CREATE 应该返回新资源的位置。这对我来说似乎很容易。客户需要能够访问新项目是完全合理的。

【讨论】:

您实际上混淆了 PUT 和 POST。 POST 用于创建,PUT 用于更新(和创建)。还值得注意的是,PUT 应该是幂等的,而 POST 不是。 一个幂等命令应该可以正常工作,无论你运行多少次。因此,您应该能够多次执行相同的 PUT 以应用相同的“更新”,而不会产生任何负面影响。【参考方案4】:

根据 RFC7231 无关紧要,可能为空

我们如何在项目中实现基于json api标准的解决方案:

post/put:输出对象属性与 get 一样(字段过滤器/关系应用相同)

删除:数据只包含空值(因为它是丢失对象的表示)

标准删除状态:200

【讨论】:

【参考方案5】:

我喜欢 Alfonso Tienda 的回应 HTTP status code for update and delete?

这里有一些提示:

删除

200(如果您想在响应中发送一些额外数据)或 204(推荐)。

202 已删除的操作尚未提交。

如果没有什么要删除的,使用204 404(DELETE操作是幂等的,删除一个已经删除的项是操作成功,所以可以返回204,但确实幂等并不一定意味着相同的响应)

其他错误:

400 错误请求(格式错误或错误查询是奇怪但可能的)。 401 未经授权身份验证失败 403 Forbidden:授权失败或无效的应用程序 ID。 405 不允许。当然。 409 资源冲突可能在复杂系统中发生。 还有501502以防出错。

PUT

如果您要更新集合的元素

200/204,原因与上面的 DELETE 相同。 202 如果操作尚未提交。

引用的元素不存在:

PUT 可以是 201(如果您创建了元素,因为那是您的行为)

404如果您不想通过 PUT 创建元素。

400 错误请求(格式错误或错误查询比 DELETE 更常见)。

401 未经授权

403 禁止:身份验证失败或无效的应用程序 ID。

405 不允许。当然。

409 资源冲突可能在复杂系统中发生,例如在 DELETE 中。

422 无法处理的实体它有助于区分“错误请求”(例如格式错误的 XML/JSON)和无效的字段值

还有501502以防出错。

【讨论】:

以上是关于按照惯例应该返回哪些 REST PUT/POST/DELETE 调用?的主要内容,如果未能解决你的问题,请参考以下文章

REST POST PUT差别

在 dstore/Rest 请求中添加查询参数

Rest模式get,put,post,delete含义与区别(转)

Rest模式get,put,post,delete含义与区别

Rest模式get,put,post,delete含义与区别(转)

使用 @PreAuthorize 时从 Spring 控制器返回 405 与 403