0

Consider the following scenario:

  1. Alice updates item1 using http put
  2. Bob updates item1 using http put with different data
  3. Alice updates item1 using http put again with the same data accidentally, for instance, using the back button in a browser
  4. Charlie reads the data

Is this idempotent?

zdenek
  • 21,428
  • 1
  • 12
  • 33
Chenxi
  • 87
  • 8
  • 1
    You can easily implement this so that 3 can't succeed, e.g. track the last modified date or revision number of the item and then Alice's request becomes "make this change to version 0", Bob's becomes "make a change to version 1" and then replaying Alice's request fails because the current version is 2 not 0. – Rup Apr 20 '18 at 10:32
  • This sounds interesting. But i will have to change every java entity class and every put method – Chenxi Apr 20 '18 at 10:50
  • Idempotency is a promise by the protocol regarding the delivery of the request and not the actual state returned by the request. On a temporary network issue, an intermediary node can just replay the request in such cases automatically. – Roman Vottner Apr 20 '18 at 12:01

2 Answers2

2

Is this idempotent?

Yes. The relevant definition of idempotent is provided by RFC 7231

A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.

However, the situation you describe is that of a data race -- the representation that Charlie receives depends on the order that the server applies the PUT requests received from Alice and Bob.

The usual answer to avoiding lost writes is to use requests that target a particular version of the resource to update; this is analogous to using compare and swap semantics on your request -- a write that loses the data race gets dropped on the floor

For example

 x = 7
 x.swap(7, 8) # Request from Alice changes x == 7 to x == 8
 x.swap(8, 9) # Request from Bob changes x == 8 to x == 9
 x.swap(7, 8) # No-Op, this request is ignored, x == 9

In HTTP, the specification of Conditional Requests gives you a way to take simple predicates, and lift them into the meta data so that generic components can understand the semantics of what is going on. This is done with validators like eTag.

The basic idea is this: the server provides, in the metadata, a representation of the validator associated with the current representation of the resource. When the client wants to make a request on the condition that the representation hasn't changed, it includes that same validator in the request. The server is expected to recalculate the validator using the current state of the server side resource, and apply the change only if the two validator representations match.

If the origin server rejects a request because the expected precondition headers are missing from the request, it can use 428 Precondition Required to classify the nature of the client error.

Community
  • 1
  • 1
VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91
0

Yes, this is idempotent. If it is wrong behavior for you, we should know bussiness logick behind that.

Егор Лебедев
  • 1,161
  • 1
  • 10
  • 26
  • Are you sure? This doesn't feel like idempotency to me. Can you cite the definition you're using here? – Rup Apr 20 '18 at 10:34
  • Idempotency behavior is when you get exactly the same output data from providing exactly same data on input every time. In this situation bob ask for item1 and get version0, after Alice change version, Bob request for item1 give him response with version1 – Егор Лебедев Apr 20 '18 at 10:40
  • OK. The definitions [on this old question](https://stackoverflow.com/q/1077412/243245) are slightly different: "has no additional effect if it is called more than once with the same input parameters", "can be repeated an arbitrary number of times and the result will be the same as if it had been done only once", "No matter how many times you call the operation, the result will be the same." etc. which is closer to what I'd remembered. – Rup Apr 20 '18 at 10:44
  • but in fairness it doesn't say what happens when the operations are repeated interleaved with other operations, so there is still something here. You're right to ask about business logic required. – Rup Apr 20 '18 at 10:51
  • Read about `pure functions`, it is functions without side effetcts, like writing to db or write something to file. So when multiple users work with one db or file, most of cases you don't have idempotency. Here you sholud care about managing different states. – Егор Лебедев Apr 20 '18 at 10:56