HTTP响应412 - 是否可以包含内容?

5
我正在构建一个RESTful数据存储,并利用条件GET和PUT。在条件PUT期间,客户端可以包含先前GET的资源的Etag,如果当前表示不匹配,则服务器将返回HTTP状态码412(前提条件失败)。请注意,这是基于Atom的服务器/协议。
我的问题是,当我返回412状态时,我是否也可以包含资源的新表示,还是必须用户发出新的GET请求?HTTP规范似乎没有明确说明,Atom规范也没有(尽管他们的示例显示响应上的空实体主体)。不返回新的表示并让客户端专门获取它似乎非常浪费。你有什么想法吗?
3个回答

4
虽然条件GET和PUT被总结为“条件请求”,但它们在概念上非常不同。条件GET是一种性能优化,而条件PUT是一种并发控制机制。很难将它们放在一起讨论。
关于条件GET的问题:如果您发送GET并包括If-None-Match标头,则如果资源已更改,则服务器将发送200 Ok,如果未更改(如果条件失败),则发送304 Not Modified。412仅应与条件PUT一起使用。
更新:似乎我稍微误读了问题。关于在条件PUT失败时刷新本地副本的问题:可能缓存已经具有最新版本,并且您的刷新GET将从某个缓存中提供。让服务器使用412返回当前实体实际上可能会导致性能更差。

是的,我一开始没有理解你的回答,但是你提到的可能存在的中间缓存点是非常好的观点。说实话,这是我迄今为止看到的最好的答案。 - Gandalf

3
不,从技术上讲你不应该这样做。错误代码通常用于指定出现了什么问题。虽然没有什么能阻止你返回内容(实际上,有些错误比如404会返回一个漂亮的页面,上面写着“您没有找到您要寻找的内容”),但响应的目的不是返回其他内容,而是返回告诉你出了什么问题的内容。从技术上讲,你也不应该返回那些数据,因为你传递了If-None-Match: etag(我假设你传递的是这个)。
另外,你真的需要优化掉一个额外的http调用吗?
越想越觉得这是个坏主意——你会在其他任何错误情况下返回内容吗?PUT语义是用于PUT操作的。GET语义应该用于GET操作。

优化掉一个HTTP调用可以轻松地意味着每天节省数百万个请求 - 所以是的,我会支持这样做。POST语义是POST - 但在成功的POST上返回内容是完全有效的,所以我不同意你的论点。 - Gandalf
你不是在进行POST请求,而是在进行PUT请求。POST语义与两者都不同,并且在POST请求中返回内容是有效的,因为语义表明:POST和PUT请求之间的根本区别反映在请求目标的不同含义上。POST请求中的URI标识将处理所包含实体的资源。该资源可以是数据接受进程、到其他协议的网关或接受注释的单独实体。这意味着POST具有返回与URI无关的内容的灵活性。 - Kylar

2
如果由于更新冲突后的额外请求而产生的附加请求数量足以引起性能问题,那么我建议您可能存在资源粒度的问题。您真的期望每天有数百万个用户同时编辑同一资源吗?也许您需要存储资源的增量更改,而不是直接更新资源。如果这些资源真的存在如此多的争用,那么用户不会一直在使用过时的数据吗?
如果您的问题是资源包含最后修改日期和最后修改用户,而且每次PUT后都必须进行GET,那么我更加认同扭曲规则的必要性。
然而,我认为额外请求的性能损耗值得为客户端开发人员提供清晰的信息。

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