PATCH requests describe how to modify a resource, if you apply the same modification twice, the result may not be the same. This is because defining how the modifications are applied is up to you, you have to define the how to interpret the contents.
A PATCH request can be idempotent if you define it to be idempotent.
Idempotent example:
// Original resource
{
name: 'Tito',
age: 32
}
// PATCH request
{
age: 33
}
// New resource
{
name: 'Tito',
age: 33
}
Non-idempotent example:
// Original resource
{
name: 'Tito',
age: 32
}
// PATCH request
{
$increment: 'age'
}
// New resource
{
name: 'Tito',
age: 33
}
A PATCH request can written in many formats, not just JSON.
In the second example I used a made up syntax for incrementing an attribute.
Clearly this is not idempotent, as sending the same request again will result in different object.
Using such a made up syntax is valid according to standards:
The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI. In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced. With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version.
Whether it is restful to use PATCH requests this way is not clear, some people consider it is not, here's a good answer about the issue.