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,632
  • 6
  • 28
  • 45
SSR
  • 75
  • 2
  • 4

3 Answers3

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
  • 40,902
  • 7
  • 64
  • 85
  • 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. – Géry Ogam 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. – Géry Ogam 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? – Géry Ogam 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
  • 859
  • 2
  • 12
  • 23
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.

Brhane Giday
  • 173
  • 1
  • 5