【问题标题】:Idempotent PUT in a concurrent environment并发环境中的幂等 PUT
【发布时间】:2015-08-25 23:01:37
【问题描述】:

上下文

我有一个 REST API,其中多个客户端(应用程序)可以使用 PUT 更新资源的状态。例如,此资源是一个可以打开ONOFF 的灯。

当系统检测到发生电力故障时,系统也会自动更新此资源,导致灯处于BROKEN 状态。我要区分BROKENOFFBROKEN里的灯不能转ON

问题

我使用<b>PUT</b> 方法来执行此操作,例如<b>PUT</b> @987654321@ { "state": "ON"}

但我不确定我是否尊重<b>PUT</b> 方法的幂等属性。 其实我有3个案例:

  • 灯是ON。上面的代码导致ON 状态。
  • 灯是ON。上面的代码导致ON 状态....酷!此时,幂等性仍然得到保证:-)!
  • 灯是BROKEN。上面的代码会导致错误,比如503 Service Unavailable

问题

我不确定是否正确理解幂等性的概念。相信我,我读了很多关于它的东西,但还是有点困惑。

据我了解,多个<b>PUT</b> 总是导致资源的相同状态:由于BROKEN,在我的情况下无法保证

但我也可以用另一种方式理解它:多个<b>PUT</b> 总是导致相同的副作用:保证,我的请求要么产生转为ON,要么什么都没有(对于BROKEN 的情况,它已经进去了)。

编辑:

我的意思是:唯一的副作用是打开ON 灯,这是有保证的(它要么打开,要么在这里什么都不做)

请看这里:Is REST DELETE really idempotent?

哪一个是正确的?根据理解,我的 REST API 是否确保幂等性......

EDIT2:

来自W3C的定义

方法还可以具有“幂等性”属性,因为(除了错误或过期问题)N > 0 个相同请求的副作用与单个请求相同。

我可以认为当它是BROKEN 时转动ON 是一个错误吗?

【问题讨论】:

    标签: api rest http idempotent


    【解决方案1】:

    幂等性意味着在一个孤立的环境中,来自同一个客户端的多个请求对资源的状态没有任何影响。如果来自另一个客户端的请求改变了资源的状态,那么它不会破坏幂等性原则。虽然,如果您真的想确保 put 请求不会最终覆盖来自不同客户端的另一个同时请求的更改,您应该始终使用 etags。详细地说,put request 应该始终提供最后一个资源状态的 etag(它来自 get request),并且只有当 etag 是最新的时才应该更新资源,否则应该引发 412(Precondition Failed)状态代码。在 412 的情况下,假设客户端再次获取资源,然后尝试更新。根据 REST,这对于防止竞争条件至关重要。

    详细说明:-

    根据 W3C(http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html),'方法还可以具有“幂等性”的属性,因为(除了错误或过期问题)N > 0 个相同请求的副作用与单个请求相同。

    Get request - {'state': 'ON'} Etag-header(say)- 123
    PUT request - {'state': 'OFF'} Etag-header - 123
    

    一些内部活动改变状态,使得新状态为{'state': 'BROKEN'}。在此偶数 etag 应更改为 124。

    put request - {'state': 'ON'} Etag-header - 123.
    

    由于 etag 标头已更改,因此返回 412 错误,该错误不会破坏 api 的幂等性(除了错误或过期问题)。

    Get request - {'state': 'BROKEN'} Etag-header - 124
    Put request - {'state': 'ON'} Etag-header - 124
    

    【讨论】:

    • (见我的编辑2)。 “对资源状态没有任何影响”是什么意思?这就是我感到困惑的地方。另请注意,将状态更新为 BROKEN 是由系统本身进行的......然后它不需要通过接口 REST 来完成。即使客户在我的情况下得到 412,如果他再次使用正确的 etag 执行相同的请求......它仍然会得到 503 - 服务不可用。所以我们又遇到了同样的问题。
    • 我的意思是,如果除了您的 put 请求之外的某些事件更新了资源,这并不意味着幂等性原则被打破。这仅意味着在单个用户环境中(没有其他人可以更改资源)资源的状态不应该由于多个请求而改变。此外,如果由于任何原因导致资源状态发生变化,则假设客户端首先获取更新的资源,然后发送 put 请求(这就是 etag 的原因)。
    • 好的,谢谢!所以基本上,因为我的灯资源的状态仅在执行 PUT ON 时更改为 ON,或在执行 PUT OFF 时更改为 OFF ...除了导致不更改资源状态的不同错误(503,此处)。 ..我可以认为我的 PUT 实现是幂等的?
    • 如果您觉得有帮助,请将其标记为正确答案。
    • 是的。但是,如果您可以使用正确的 etag 标头编辑最后一个 put 请求,那就太好了……这会导致 503,然后不会破坏幂等性(与 412 错误的原因相同)
    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 2014-04-01
    • 2011-10-24
    • 1970-01-01
    • 2018-05-31
    • 1970-01-01
    • 1970-01-01
    • 2017-07-09
    相关资源
    最近更新 更多