在REST中,我应该在响应PUT时返回表示吗?

22

可以想象在此期间另一个客户端也修改了资源的其他方面。所以,尽管会增加带宽开销,将完整表示包含在PUT响应中始终是最佳实践吗?


返回与交易相关的唯一标识符是否更好?这样可以节省带宽,并避免在中间期间必须返回服务器以确保没有发生任何事情。即使返回数据,它也可能过时。 - jldupont
1
这太巧了...20分钟前我也在问自己同样的问题... - skaffman
4个回答

19

在许多情况下(如果不是大部分情况),即使通过PUT创建或更新资源,服务器也会添加一些内容。这些内容可能是时间戳、版本号或从其他元素计算而来的任何元素。即使您遵循RESTful方法并且不使用PUT进行部分更新,这仍然是真实的。

由于这个原因,对于PUT请求,返回已更新或已创建资源的表述通常是一个好主意。但如果您PUT一个2GB大小的大图片文件,您可能不希望将其作为响应的一部分返回,虽然我不一定会称之为“最佳实践”。

另一方面,包含ETag绝对值得成为“最佳实践”。


我喜欢这个答案,因为它提到了如何返回资源可以帮助解决问题,但也坚持了这并不总是一个好主意的事实。值得注意的一点是,这种响应很遗憾不能被缓存,因为目前没有机制使PUT缓存来自响应的表示。Rfc7231 描述了请求的机制,但仅在服务器未添加任何内容到资源时才起作用(请参见此评论)。 - Slawomir Brzezinski

8
Jldupont的评论指引了我正确的方向。我将使用ETags来确定资源是否已被修改,通过使用If-match头进行有条件的PUT请求(如此描述)。当发生冲突时,我会让用户决定是从服务器获取最新表示(GET),还是覆盖自己的更改。
因此,在响应PUT请求时没有必要返回完整的表示来帮助检测和解决冲突。

7

我喜欢认为GET和DELETE是一对,它们仅接受ID。

POST和PUT也像是一对。它们接受序列化对象并使其持久化。因此,我认为POST和PUT都应该返回所创建的结果对象。

在某些情况下,您可能需要在持久化过程中进行其他计算,并且PUT可以反映这些计算结果。从技术上讲,这可能会违反第三范式,因为您已经得到了派生值。但通常,Web服务的整个目的就是作为POST和可能是PUT的增值计算的一部分。


我很欣赏您的哲学观点,但是我不完全同意。HTTP规范并没有像它对GET请求所做的那样要求/禁止/限制DELETE请求只能使用URL。更重要的是,您 不是 唯一一个认为这种情况的人(而且更重要的是,像Talend这样的大型软件项目都是基于这种假设设计的)。单个实体的DELETE请求不需要主体(就像GET请求),但是如果没有一些细化请求的数据,针对集合的DELETE请求将会非常激进。 - Anthony

3
您可以考虑返回303 See Other响应,并将Location头设置为更新后的资源URI(Post/Redirect/Get)。这样,即使在编辑间隙中更改了资源,客户端也可以收到当前状态的资源(如果选择遵循Location头部),并且不会因使用浏览器而重新提交请求。
然而,这种模式排除了发送适当的成功代码(200 OK202 Accepted等),这对客户端可能是有用的。此外,根据您对REST的定义,您可能认为这是非标准做法。
如果客户端可能是由人操作的浏览器,则可能更合适。

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