The Problem: Partial Updates in HTTP APIs
REST APIs that use PUT require the client to send the entire resource representation, even when only one field needs to change. For large resources, this is wasteful and creates concurrency issues: two clients reading, modifying, and writing the same resource may overwrite each other's changes.
HTTP defines a PATCH method (RFC 5789) for partial updates, but PATCH does not specify a patch format — it leaves that to the media type. Two standards emerged to fill this gap: RFC 6902 (JSON Patch, published April 2013) and RFC 7396 (JSON Merge Patch, published October 2014). They solve the same problem with very different philosophies.
How Merge Patch Works
A JSON Merge Patch is simply a JSON object that describes the intended state of the target. The merge algorithm is intuitive:
- Keys in the patch that have non-null values are set on the target.
- Keys in the patch that have null values are deleted from the target.
- Keys in the target that do not appear in the patch are left unchanged.
Example: given target {"a": 1, "b": 2, "c": 3} and patch {"b": 20, "c": null}, the result is {"a": 1, "b": 20}. The key c is deleted because its patch value is null; a is unchanged because it does not appear in the patch.
The media type for merge patch is application/merge-patch+json. A PATCH request with this Content-Type and a merge patch body is all that's needed.
Merge Patch vs. JSON Patch (RFC 6902)
JSON Patch (RFC 6902) is more expressive: it supports add, remove, replace, move, copy, and test operations, applied atomically. It can target deeply nested values via JSON Pointer paths. If any operation fails, the entire patch is rolled back.
JSON Merge Patch trades expressiveness for simplicity. A merge patch is itself a valid JSON object — easy for humans to read, write, and reason about. Its algorithm can be stated in a few lines of pseudocode. There are no operation types to learn, no path syntax, no atomicity semantics.
The tradeoff is capability: merge patch cannot express array manipulation (you can only replace a whole array, not insert or remove elements), cannot move values between keys, and cannot set a field to null (since null means deletion).
Limitations
The null-means-delete convention is the most significant practical limitation of merge patch. If your data model uses null as a meaningful value (e.g., a field can be explicitly set to null to indicate "not provided"), merge patch cannot distinguish between "set this field to null" and "delete this field". For such data models, JSON Patch is the better choice.
Arrays are another limitation. Merge patch can only replace an array wholesale. If you need to append, remove, or reorder items in an array without replacing the entire array, you need JSON Patch or a custom PATCH body format.