代码之家  ›  专栏  ›  技术社区  ›  Mark Lutton

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

  •  11
  • Mark Lutton  · 技术社区  · 16 年前

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

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

    RESTfulWeb服务中的经验法则是尽可能遵循HTTP的详细信息。在这种情况下,如果版本不匹配,在请求中使用条件头并返回412 precondition failed会更好吗?如果匹配,则显示相应的标题。此头接受etag(实体标记),它可能是资源当前状态表示的哈希。

    如果我这样做,ETags将是为了外观,因为版本仍然是我要测试的真正的东西。

    除了“让它更安静”之外,还有什么理由我应该这样做吗?不管这是什么意思?

    1 回复  |  直到 13 年前
        1
  •  19
  •   mogsie    16 年前

    如果您正在使用HTTP,那么要做的适当的事情就是始终遵循HTTP规范,原因只是为了让理解该规范的人能够 功能正常 .

    只有在有前提条件的情况下才应使用412 (例如,如果匹配)导致版本匹配失败,而 如果实体会导致冲突,则应使用409 (HTTP规范本身在 definition of 409 )

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

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

    但是,完全在实体体内进行并不被禁止。它只需要您解释这个概念以及它是如何工作的,而对于ETag解决方案,您只需要向人们指出HTTP规范。

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