HTTP状态412(前置条件失败)和数据库版本控制

HTTP状态412(前置条件失败)和数据库版本控制,http,rest,http-status-code-412,Http,Rest,Http Status Code 412,我正在实现一个访问数据库的RESTful web服务。对数据库中的实体进行版本控制,以检测多个更新。例如,如果当前值是{“name”:“Bill”,“comment”:“tinker”,“version”:3},如果一个用户输入{“name”:“Bill”,“comment”:“tailor”,“version”:3},请求将成功(200 OK),新值将是{“name”:“Bill”,“comment”:“tailer”,“version”:4}。如果第二个用户输入{“name”:“Bill”,

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

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

RESTful web服务中的一条经验法则是尽可能遵循HTTP的详细信息。在这种情况下,在请求中使用条件标头并在版本不匹配时返回412 Premission Failed是否更好?适当的标头似乎是if match。此标头采用ETag(实体标记)这可能是资源当前状态表示的哈希

如果我这样做了,ETag将是为了外观,因为版本仍然是我测试的真实对象


除了“使其更加RESTful”之外,还有什么理由我应该这样做吗?如果您使用HTTP,那么适当的做法是始终遵循HTTP规范,原因只是允许理解规范的人正确地运行

412仅当前提条件(例如,如果匹配)导致版本匹配失败时才应使用,而409则应在实体将导致冲突时使用(HTTP规范本身在中提及此行为)

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

我会坚持一种方法,你说“数据库模式不能更改”,但这并不阻止你(就在HTTP服务器层)从datbase表示中提取版本并将其放入ETag,然后在输入的过程中,获取If Match头并将其放回version字段

但是,完全在实体体中进行这项工作并不是禁止的。它只要求您解释概念及其工作原理,而使用ETag解决方案,您只需将人们引向HTTP规范即可


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

关于我的问题,你有什么线索吗:“版本标志不必是当前资源的散列。”“-如果您想降低用户猜测预期版本并绕过并发检查的风险,它就可以了。呵呵:-)我并不是说{{ETag:“3”}是个好主意。。。使其不透明通常是一个好主意,尽管它会降低可见性。考虑{{EtAG:“3:ECCBC8”}——其中“ECCBC8”是字符“3”的Md5SUM的前6个字符。这迫使客户端使用他们想要的方式的实体标记;但是保持可见性(“3”是存在的,所以人类可以将其解释为“版本3”)。我们仍然不散列实际内容。