如何在使用版本控制

时间:2018-04-24 11:04:29

标签: rest http

我知道REST PUT操作应该是幂等的。我知道它们的目的是支持版本控制(因此,如果我尝试更新旧版本4的对象,但新版本为5,我应该得到409冲突响应。但是处理幂等性的正确方法是什么版本化?

我们说我的对象有一个版本和一个数据字段(例如' name')。如果我当前的对象位于/ objects / 1,并且版本1的名称为' alice',我想用nam' bob'将其更新为版本2,我可能会发送版本为2的PUT并命名为' bob'。但是因为它是幂等的,我应该能够重复发送它,并且效果与单个调用相同。后续调用通常会使版本控制检查失败,除了它们的其他数据将与服务器上的数据匹配,并且可以被检测为(或至少假设为)重复请求。

对所有重复呼叫的响应是否相同(例如200 OK或204 No Content)?或者响应代码是否应指示调用是否实际进行了更改(并增加了版本),或者是否将其检测为重复调用(否则将标记为409冲突,除了PUT中的数据是与已有的相同)?如果它应该表明差异,那么在响应中区分它们的适当方法是什么?

而且,我想我还应该问一下REST版本控制是否通常在对象中完成(例如,使用REST对象的版本字段),或者是否在REST协议中完成(例如作为HTTP字段,保持对象"清洁")?

1 个答案:

答案 0 :(得分:1)

  

对所有重复呼叫的响应是否相同(例如200 OK或204 No Content)?

是 - HTTP规范的相关部分位于RFC 7232。查看If-Match的说明:

  

如果收到的If-Match条件的计算结果为false,则原始服务器不得执行请求的方法;相反,原始服务器必须响应a)412(前提条件失败)状态代码或b)2xx(成功)状态代码之一,如果原始服务器已经验证正在请求状态更改并且最终状态已经反映在目标资源的当前状态(即,用户代理请求的更改已经成功,但用户代理可能不知道它,可能是因为先前的响应丢失或其他一些人进行了兼容的更改用户代理)。在后一种情况下,原始服务器不得在响应中发送验证器头字段,除非它可以验证该请求是否是由同一用户代理立即进行的更改的重复。

我对此的解读是服务器 要验证更改是否已成功;但是如果它执行了这样的检查,并希望将结果传达给客户,那就是做到这一点的方法。

我没有看到为什么相同的逻辑不适用于您可能会使用409 Conflict状态代码的原因。

  

我想我也应该问一下REST版本是否通常在对象中完成(例如,使用REST对象的版本字段),或者是否在REST协议中完成(例如作为HTTP字段,保留对象& #34;清洁"?)

并非所有媒体类型都可以方便地在资源表示中嵌入版本控制元数据(我们对用于json文档的图像使用相同的PUT),所以我猜想更常见的是查看版本控制信息在元数据中(也就是说,在RFC 7232所描述的标题中)。

  

如果它应该表明差异,那么在响应中区分它们的适当方法是什么?

未指定;你可以做那里有意义的事情。在"成功"的情况下,您应该发送"表示行动的状态"以及2xx类状态代码(请参阅RFC 7231 6.3.1)。使用409 Conflict / 412 Precondition Failed - 由于这些状态代码是4xx类的成员,因此您应该发送一个包含错误情况解释的表示,以及它是临时的还是永久的条件" (见RFC 7231 6.5)。

查看RFC 7807 Problem Details for HTTP APIs中的示例可能会有所帮助。