6

语境

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

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

问题

我使用PUT 方法来做到这一点,比如PUT http://address:port/my_lamp { "state": "ON"}

但我不确定我是否尊重PUT方法的幂等性。事实上,我有3个案例:

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

问题

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

在我的理解中,多个PUT总是导致资源的相同状态:在我的情况下不能保证,因为BROKEN

但我也可以用另一种方式理解它:多重PUT总是导致相同的副作用:保证,我的请求要么产生 turn ON,要么什么都没有(对于这种BROKEN情况,它已经存在)。

编辑:

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

看这里:REST DELETE 真的是幂等的吗?

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

编辑2:

W3C的定义

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

我可以认为打开灯是错误ONBROKEN吗?

4

1 回答 1

10

幂等性意味着在孤立的环境中,来自同一客户端的多个请求对资源状态没有任何影响。如果来自另一个客户端的请求改变了资源的状态,那么它不会破坏幂等性原则。虽然,如果您真的想确保 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
于 2015-06-11T08:03:13.343 回答