HTTP状态412(前提条件失败)和数据库版本控制 [英] HTTP Status 412 (Precondition Failed) and Database Versioning

查看:4236
本文介绍了HTTP状态412(前提条件失败)和数据库版本控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现一个访问数据库的RESTful Web服务。对数据库中的实体进行版本控制以检测多个更新。例如,如果当前值为 {name:Bill,comment:tinker,version:3} ,如果一个用户PUTs {name:Bill,comment:tailor,version:3} ,请求将成功(200 OK),新值将为 {name:Bill,comment:tailor,version:4} 。如果第二个用户PUTs {name:Bill,comment:sailor,version:3} 该请求将失败(409 Conflict)因为版本号不匹配。

I am implementing a RESTful web service that accesses a database. Entities in the database are versioned to detect multiple updates. For instance, if the current value is {"name":"Bill", "comment":"tinker", "version":3}, if one user PUTs {"name":"Bill", "comment":"tailor", "version":3}, the request will succeed (200 OK) and the new value will be {"name":"Bill", "comment":"tailor", "version":4}. If a second user PUTs {"name":"Bill", "comment":"sailor", "version":3"} that request will fail (409 Conflict) because the version number does not match.

存在非RESTful接口,因此无法更改数据库的设计.RESTful接口调用处理的现有接口检查版本的详细信息。

There are existing non-RESTful interfaces, so the design of the databases cannot be changed. The RESTful interface calls an existing interface that handles the details of checking the version.

RESTful Web服务中的经验法则是尽可能遵循HTTP的详细信息。在这种情况下使用请求中的条件头并返回412 Precondition如果版本不匹配则失败?相应的头看起来是If-Match。这个头带有一个ETag(实体标签),它可能是当前状态表示的哈希值资源。

A rule of thumb in RESTful web services is to follow the details of HTTP whenever possible. Would it be better in this case to use a conditional header in the request and return 412 Precondition Failed if the version does not match? The appropriate header appears to be If-Match. This header takes an ETag (Entity Tag) which could be a hash of the representation of the current state of the resource.

如果我这样做的话,ETags会出于外表的缘故,因为版本仍然是我正在测试的真实内容。

If I did this, the ETags would be for appearances' sake, because the version would still be the real thing I'm testing for.

我有什么理由这样做,除了使它更加RESTful,无论这意味着什么?

Is there any reason I should do this, other than "making it more RESTful", whatever that is supposed to mean?

推荐答案

适当的事情是做到如果您使用的是HTTP,请遵循HTTP规范,原因只是让了解规范的人正确运行

The appropriate thing to do is always to follow the HTTP spec if you're using HTTP, and the reason is simply to allow people who understand the spec to function correctly.

412只应在前提条件时使用(例如If-Match)导致版本匹配失败,而如果实体会导致冲突,则应使用 409 (HTTP规范本身在 409的定义)。

412 should only be used if a precondition (e.g. If-Match) caused the version matching to fail, whereas 409 should be used if the entity would cause a conflict (the HTTP spec itself alludes to this behaviour in the definition of 409).

因此,不发送ETag的客户端将不会期望412.相反,发送ETag的客户端将不会理解它是导致409的ETag。

Therefore, a client that doesn't send ETags won't be expecting a 412. Conversely, a client that does send ETags won't understand that it's ETags that are causing a 409.

我会坚持一种方式。你说数据库模式不能改变,但这并不能阻止你(在HTTP服务器层中)从数据库表示中提取版本并将其放入ETag,然后在途中,获取If-Match标头并将其放回版本字段。

I would stick with one way. You say that "the database schema can't change", but that doesn't stop you (right in the HTTP server layer) to extract the version from the datbase representation and put it in the ETag, and then on the way in, take the If-Match header and put it back in the version field.

但不禁止在实体主体中完全执行此操作。它只需要您解释概念及其工作原理,而使用ETag解决方案,您可以将人们指向HTTP规范。

But doing it completely in the entity body itself isn't forbidden. It just requires you to explain the concept and how it works, whereas with the ETag solution you can just point people to the HTTP spec.

编辑:版本标志不必是当前资源的哈希值;一个版本是完全可以接受的 ETag:3是完全有效的ETag。

And the version flag doesn't have to be a hash of the current resource; a version is quite acceptable. ETag: "3" is a perfectly valid ETag.

这篇关于HTTP状态412(前提条件失败)和数据库版本控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆