4

I have read lots of places that HTTP Patch is non-idempotent. Can someone explain me why it is non-idempotent ? Because as per the definition - Idempotent methods may or may not change the resource state, but repeated requests should have no further side effects after the first request. How a repeated PATCH request can change the Resource state?

GoBusto
  • 4,384
  • 6
  • 25
  • 39
SSR
  • 65
  • 2
  • 4

4 Answers4

6

There's some confusion about that. The PATCH method is not required to be idempotent, that's the point. Clients can't assume their PATCH requests will be idempotent, as they can do with PUT and GET.

If a particular implementation will be idempotent or not usually depends on the patching algorithm being used, if any. For instance, a poor implementation that's not using a diff format that validates the current values won't be idempotent.

Pedro Werneck
  • 39,587
  • 6
  • 57
  • 82
  • Yes. Above explanation makes sense. Thanks for answering :) – SSR Mar 22 '15 at 13:00
  • Sorry but you can make *non* idempotent PATCH requests even with a diff format like [JSON Patch](https://tools.ietf.org/html/rfc6902). For instance by appending items to an array: `{"op": "add", "path": "/-", "value": "foo"}` transforms `[]` to `["foo"]` the 1st time, then to `["foo", "foo"]` the 2nd time, then to `["foo", "foo", "foo"]` the 3rd time, etc. – Maggyero Feb 11 '19 at 08:31
  • @Maggyero "not using a diff format that **validates the current values**" – Pedro Werneck Feb 12 '19 at 09:43
  • I don't see how validation relates to idempotence. Appending to an array, validated or not, will never be idempotent. – Maggyero Feb 12 '19 at 11:02
  • Indeed, because appending to an array is not a diff-like operation. – Pedro Werneck Feb 16 '19 at 15:06
  • Really? How do you define a diff-like operation if you exclude the add operation? – Maggyero Feb 20 '19 at 19:55
2

Yes, there is a lot of discussion & confusion how PUT and PATCH differ. The clear is:

PUT

  • request must contain whole representation of given resource
  • is idempotent (client can be sure for 100%)

PATCH

  • request contains just subset (just attributes we want to update)
  • is not required to be idempotent (quite often is idempotent, but it is not rule, so client cannot be 100% sure in this)

From those rules, we can deduce some rules we need to implement in the backend, e.g.:

a)

  • GET: users/1; response body {username: 'john', email: 'old@email.com'}
  • PUT: users/1; request body {username: 'john'}

Either sever send validation error from API (missing email) or email will be deleted.

I really hope that API should return validation error. So to delete some value, client should call (explicitly email: null mentioned in the request):

  • PUT: users/1; request body {username: 'john', email: null}

b)

  • PATCH: users/1; request body {username: 'john'}

No change on the server. To delete value, client should send:

  • PATCH: users/1; request body {email: null}

Both examples above are idempotent.

In the other discussion is example that PATCH is non-idempotent if patch is doing something like "add" to the collection in the backend: Use of PUT vs PATCH methods in REST API real life scenarios

sasynkamil
  • 789
  • 2
  • 9
  • 20
0

I have a scenario in which PATCH will not be idempotent:

Lets assume two different clients are sending HTTP Requests.
Client X
Client Y

Client X
(1) PATCH {"age":"10"}
response1-> {"age":"10", "sex":"f","name":"a"}

Client Y
(2) PATCH {"name":"b"}
response2-> {"age":"10", "sex":"f","name":"b"}

Client X
(3) PATCH {"age":"10"}
response3-> {"age":"10", "sex":"f","name":"b"}

You can see that even if requests (1) and (3) are the same, the responses differ. The "name" in the 3rd response is "b".

If this is a valid scenario it can be a prove that PATCH method can respond with different responses even if requests are the same. That would never happen with PUT method, which should send the whole object with all fields {age,sex,name}.

fascynacja
  • 1,287
  • 2
  • 12
  • 28
  • That's not how an idempotent request works. It's the manipulation of the resource on the server, not the response. Think of an HTTP DELETE request: When you invoke N similar DELETE requests, first request will delete the resource and response will be 200 (OK) or 204 (No Content). Other N-1 requests will return 404 (Not Found). Clearly, the response is different from first request, but there is no change of state for any resource on server side because original resource is already deleted. So, DELETE is idempotent. – brsfan Mar 20 '20 at 12:36
  • my example proves that: making multiple identical requests does not have the same effect as making a single request – fascynacja Mar 20 '20 at 14:05
0

A PATCH is not necessarily idempotent, although it can be. Contrast this with PUT; which is always idempotent. The word "idempotent" means that any number of repeated, identical requests will leave the resource in the same state. For example, if an auto-incrementing counter field is an integral part of the resource, then a PUT will naturally overwrite it (since it overwrites everything), but not necessarily so for PATCH.