Why PATCH is neither safe nor idempotent?

16,809

Solution 1

It's not safe because in general you can't safely execute a PATCH request without changing a resource (That's what it's for).

So why is PATCH not idempotent compared to PUT? It's because it matters how you apply your changes. If you'd like to change the name property of a resource, you might send something like {"name": "foo"} as a payload and that would indeed be idempotent since executing this request any number of times would yield the same result: The resources name attribute is now "foo".

But PATCH is much more general in how you can change a resource (check this definition on how to apply a JSON patch). It could also, for example, mean to move the resource and would look something like this: { "op": "move", "from": "/a/b/c", "path": "/a/b/d" }. This operation is obviously not idempotent since calling at a second time would result in an error.

So while most PATCH operations might be idempotent, there are some that aren't.

One remark on the other answers: Idempotence is defined by repeating an operation multiple times in a row. Saying that something is not idempotent because the effect is different if some other operation was executed in between or in parallel just isn't a valid argument (no operation would be idempotent in general if that was the case). Mathematically, an idempotent transformation is one that yields the same result, no matter how often you apply it (like rotating something 360 degrees). Of course two 360 deg rotation might yield different results if you apply any other operation in between.

Solution 2

I recently started looking if Patch is idempotent or not and after reading about the JSON patch format, i understood that if the add operation is applied using the Patch method its completely possible that the request is non-idempotent as it could add the new values to an existing resource if the same request is made multiple times.

{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }

Solution 3

PATCH changes the resources attributes. The change may require a concrete previous value of the attribute, which makes it NON idempotent.

From Name=John to Name=Gargantua. 

After repeated applying the name will be Gargantua and patch will fail, since it requires the name to be "John" before the change

"from Name=John"

Share:
16,809
Tony Vincent
Author by

Tony Vincent

Dust

Updated on June 17, 2022

Comments

  • Tony Vincent
    Tony Vincent almost 2 years

    I have trouble understanding why PATCH is not safe where PUT is. Aso the idempotent part - if I update a field of the resource, wouldn't that field return the same value after update?