RESTful 'PUT' 操作是不是应该返回一些东西......

Posted

技术标签:

【中文标题】RESTful \'PUT\' 操作是不是应该返回一些东西......【英文标题】:Should a RESTful 'PUT' operation return something....RESTful 'PUT' 操作是否应该返回一些东西...... 【发布时间】:2010-10-22 07:42:41 【问题描述】:

我想知道人们对 RESTful PUT 操作的看法是什么,该操作在响应正文中不返回任何内容 (null)。

【问题讨论】:

【参考方案1】:

HTTP 规范 (RFC 2616) 有许多适用的建议。这是我的解释:

HTTP 状态码 200 OK 成功 PUT 更新到 现有资源。不需要响应体。 (根据Section 9.6,204 No Content 更合适。) HTTP 状态码 201 Created 用于成功 PUT 新 资源,在 Location 标头字段中返回新资源的最具体 URI,以及在响应正文中回显的资源的任何其他相关 URI 和元数据。 (RFC 2616 Section 10.2.2) HTTP 状态代码 409 Conflict 用于不成功的 PUT 到第 3rd 方修改,并列出差异 在尝试更新和响应中的当前资源之间 身体。 (RFC 2616 Section 10.4.10) HTTP 状态码 400 Bad Request 表示不成功 PUT,响应正文中包含自然语言文本(例如英语) 这就解释了为什么 PUT 失败了。 (RFC 2616 Section 10.4)

【讨论】:

@stian 有趣!这对 Mozilla 来说似乎很冒昧,因为我在 RFC 2616(特别是 10.2 Successful 2xx 和 10.2.1 200 OK 部分)中找不到任何明确排除将 200 用于 PUT、DELETE 或任何其他方法的内容。我错过了什么?比如Mozilla成为W3和IETF的老大? ;) 或者他们可能只是从未听说过 Postel 的稳健性原则。 @stian:这句话于 2013 年 2 月 3 日被删除。可能是因为有人在这里读到了它。 ;) developer.mozilla.org/en-US/docs/HTTP/… PUT 方法的语义是忽略资源处于的任何当前状态,因此只有在请求为有条件的。 @systemPAUSE 不错的答案。一个小点:如果您不打算将响应正文返回到成功的操作,我建议只使用 204。一些客户端(例如 jQuery Ajax)如果期望一个非零长度的响应但没有得到它,将会阻塞。你可以看到这个in this question的例子。 可能 RFC2616 已经更新,因为这个问题得到了回答。在 9.6 中没有提到与 200 相关的 No response body needed。事实上,与 PUT 相关的响应主体根本没有被提及。它只声明If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.【参考方案2】:

与这里的大多数答案相反,我实际上认为 PUT 应该返回更新的资源(当然除了 HTTP 代码)。

您之所以希望将资源作为 PUT 操作的响应返回是因为当您向服务器发送资源表示时,服务器也可以对该资源进行一些处理,因此客户端想知道如何请求成功完成后,此资源是否看起来像。 (否则它将不得不发出另一个 GET 请求)。

【讨论】:

@Raedwald 确定是的。 REST 不要求在 PUT 上更新 整个 资源,尽管通常建议这样做。某些字段可能对更新没有意义——例如,创建日期或上次修改日期可能不应该包含在 PUT 正文中,但可能会因 PUT 而更改。话虽如此,我不同意 LiorH 的观点,即 PUT 应该导致资源返回;在 PUT 之后我需要一个 GET 来获取更新的资源。 @Randolpho REST 不需要在 PUT 上更新整个资源这不应该是 PATCH 的情况吗? @MarcoCiambrone 是的,我同意并且我撤回我之前的评论。我改变了我对 REST 和 PUT 的看法——PUT 应该始终是幂等的,并且永远不应该用于部分更新。除非支持 PATCH,否则 POST 是唯一的选择,在这种情况下,PATCH 可能是一个不错的选择。但是,PATCH 是一个新动词,某些服务器端框架可能不支持。 答案早在 rfc7231 之前就写好了,但是section 4.3.4 明确表示“PUT 方法要求创建目标资源的状态或将其替换为请求中包含的表示定义的状态消息负载” 如果更新的对象很大怎么办?返回大量不太可能使用的数据似乎很浪费。【参考方案3】:

我认为服务器可以返回内容以响应 PUT。如果您正在使用允许侧载数据的响应信封格式(例如 ember-data 使用的格式),那么您还可以包含可能已通过数据库触发器等修改的其他对象。(侧载数据明确用于减少# 个请求,这似乎是一个优化的好地方。)

如果我只是接受 PUT 并且没有要报告的内容,我会使用没有正文的状态代码 204。如果我有什么要报告的,我会使用状态码 200,并包含一个正文。

【讨论】:

【参考方案4】:

HTTP/1.1 spec(第 9.6 节)讨论了适当的响应/错误代码。但是它没有解决响应内容。

你会期待什么?一个简单的 HTTP 响应代码(200 等)对我来说似乎很简单明了。

【讨论】:

是的,但是如果您想检查在 PUT 或 POST 之后插入到 db 中的数据是否真的代表了您想要的真实数据。如果 HTTP 可以发回响应的正文会更好。 @tnkh 你的建议完全是一个可怕的想法。成功更新后进行单独的 GET 调用以实现您想要的。如果您在该部门遇到问题,为了确保性能,请引入缓存层。我们无法通过搞乱“一切顺利”的逻辑来解决这些问题。不要乱用“扎实”和基本的编程原则,这在 2020 年应该是常识。这是一种耻辱! @XDS 我承认你评论的第一部分。但在那之后就忍不住翻白眼。搞笑评论 感谢您详细说明为什么您觉得它很搞笑。【参考方案5】:

如果REST API的后端是SQL关系型数据库,那么

    您应该在每条可更新的记录中包含 RowVersion(以避免lost update problem) 您应该始终在 PUT 之后返回记录的新副本(以获取新的 RowVersion)。

如果您不关心丢失的更新,或者如果您想强制您的客户在 PUT 之后立即执行 GET,那么不要从 PUT 返回任何内容。

【讨论】:

【参考方案6】:

Http 方法“PUT”可能会根据传递的请求 URI 上的执行状态而具有不同的 Http 状态。下表可能有助于理解 -

【讨论】:

【参考方案7】:

“已创建”的 201 Http 响应代码以及“位置”标头指向客户端可以找到新创建的资源的位置。

【讨论】:

PUT 对象不是(或不应该是)新创建的资源 @kdazzle PUT 当然可以是一个新创建的资源,而且经常是。 w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6 只是为了更好地解释我的评论。 PUT 的意思是,将这个项目放在这个特定的位置,替换当前的位置(如果适用)。 对,“替换现有的”是关键词。它应该已经存在并且正在被替换。 PUT 不应该用于创建新资源。 @KevinM 和最新的RFC doc rfc7231一样,表示可以创建资源:“PUT方法要求目标资源的状态是created或替换[ ...]”,而您认为 PUT 无法创建新资源的原因是因为您不一定知道新资源的位置。但是如果你知道它的位置/标识符,如果它还没有,可以创建【参考方案8】:

我在我的服务中使用了 RESTful API,以下是我的看法: 首先我们得有个共同的看法:PUT是用来更新资源而不是create或者get的。

我使用以下方式定义资源:Stateless resourceStateful resource

无状态资源 对于这些资源,只要返回一个空体的HttpCode就够了。

有状态资源 例如:资源的版本。对于这种资源,需要修改的时候必须提供版本,所以返回完整的资源或者返回版本给客户端,这样客户端在更新动作后就不需要再发送get请求了。

但是,对于一个服务或者系统来说,保持simpleclearlyeasy to use and maintain是最重要的。

【讨论】:

"PUT 用于更新资源而不是创建或获取。" - 这既不真实也不常见。根据规范,PUT 可以创建资源。清除 = 遵循众所周知的规范。【参考方案9】:

正如空的请求正文符合 GET 请求的原始目的,而空的响应正文符合 PUT 请求的原始目的。

【讨论】:

【参考方案10】:

似乎没问题...虽然我认为成功/失败/发布时间/收到的#字节/等的基本指示。会更好。

edit:我在考虑数据完整性和/或记录保存;元数据(例如 MD5 哈希或接收时间的时间戳)可能对大型数据文件有所帮助。

【讨论】:

状态响应标头中的 200 OK 怎么样?是否认为这足以说,“工作得很好,谢谢?” 响应标头将包含状态代码,是的,我们现在正在谈论 HTTP :)【参考方案11】:

理想情况下,它会返回成功/失败响应。

【讨论】:

但不在响应正文中。 HTTP 状态代码就是这样做的地方。如果出现错误,可能会在响应 bidy 中返回一些扩展的错误信息【参考方案12】:

HTTP 响应的标头和正文之间存在差异。 PUT 永远不应返回正文,而必须在标头中返回响应代码。成功就选200,不成功就选4xx。没有空返回码之类的东西。为什么要这样做?

【讨论】:

RFC 上没有关于“PUT 永远不应该返回正文”的声明的参考。此外,如果您选择返回 200,这意味着您可能确实返回了一个主体(除非您选择 204)

以上是关于RESTful 'PUT' 操作是不是应该返回一些东西......的主要内容,如果未能解决你的问题,请参考以下文章

IIS 7.5 + 为 RESTFul 服务启用 PUT 和 DELETE,无扩展

RESTful Web 服务四种操作POST/DELETE/PUT/GET

RESTFUL设计风格

RESTful理解

以 RESTful 方式递增资源计数器:PUT 与 POST

RESTful规范