Files
json/api/basic_json/merge_patch/index.md
T
2026-10-26 21:24:35 +00:00

127 lines
5.3 KiB
Markdown

# nlohmann::basic_json::merge_patch
```
void merge_patch(const basic_json& apply_patch);
```
The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value.
The function implements the following algorithm from Section 2 of [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
```
define MergePatch(Target, Patch):
if Patch is an Object:
if Target is not an Object:
Target = {} // Ignore the contents and set it to an empty Object
for each Name/Value pair in Patch:
if Value is null:
if Name exists in Target:
remove the Name/Value pair from Target
else:
Target[Name] = MergePatch(Target[Name], Value)
return Target
else:
return Patch
```
Thereby, `Target` is the current object; that is, the patch is applied to the current value.
## Parameters
`apply_patch` (in) : the patch to apply
## Exception safety
Basic guarantee: if an exception is thrown during the operation, the JSON value may be partially modified.
## Complexity
Linear in the total number of values (including nested ones) in `apply_patch`, times the cost of a key-based object operation (looking up, adding, or erasing a member): logarithmic for [`json`](https://json.nlohmann.me/api/json/index.md), and linear for [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md) (see [`ordered_map` complexity](https://json.nlohmann.me/api/ordered_map/#complexity)). For `ordered_json`, patching an object that has `n` members with a patch that has `m` members therefore takes O(n·m). The cost also includes one copy of `apply_patch` (see the notes below).
## Notes
- `apply_patch` may be `*this` itself or refer to a value contained in `*this` (for example, a subobject returned by `(*this)[key]`); it is read as it was when `merge_patch()` was called, before any modification of `*this`. To make this possible, the function copies `apply_patch` before it modifies `*this`, so the cost includes one copy of the patch.
- A merge patch uses `null` to remove a member, so it cannot set a member to `null`: applying `{"a":null}` to `{"a":1}` gives `{}`.
- Arrays are not merged: an array in the patch replaces the target value as a whole, and a `null` inside an array is kept as an element. `null` members of the target that the patch does not mention are preserved.
- A `null` in the patch only removes a member; it does not prevent the creation of the enclosing objects. Applying `{"a":{"b":null}}` to `{}` gives `{"a":{}}` (see example 15 in Appendix A of the RFC).
- If `apply_patch` is not an object, it replaces the target as a whole. In particular, a `null` patch turns the target into `null`. If `apply_patch` is an object and the target is not, the target is first replaced by an empty object, so applying `{}` to `1` gives `{}`.
- A merge patch cannot express every change; for example, it cannot reorder array elements or remove a specific array element. Use [JSON Patch](https://json.nlohmann.me/features/json_patch/index.md) ([RFC 6902](https://tools.ietf.org/html/rfc6902)) for that. [`merge_diff`](https://json.nlohmann.me/api/basic_json/merge_diff/index.md) has a matching limitation, see its notes.
- A [discarded](https://json.nlohmann.me/api/basic_json/is_discarded/index.md) value is treated like any other non-object value: a discarded `apply_patch` turns the target into a discarded value, and an object patch replaces a discarded target by an object as described above.
## Examples
Example
The following code shows how a JSON Merge Patch is applied to a JSON document.
```
#include <iostream>
#include <nlohmann/json.hpp>
#include <iomanip> // for std::setw
using nlohmann::json;
using namespace nlohmann::literals;
int main()
{
// the original document
json document = R"({
"title": "Goodbye!",
"author": {
"givenName": "John",
"familyName": "Doe"
},
"tags": [
"example",
"sample"
],
"content": "This will be unchanged"
})"_json;
// the patch
json patch = R"({
"title": "Hello!",
"phoneNumber": "+01-123-456-7890",
"author": {
"familyName": null
},
"tags": [
"example"
]
})"_json;
// apply the patch
document.merge_patch(patch);
// output original and patched document
std::cout << std::setw(4) << document << '\n';
}
```
Output:
```
{
"author": {
"givenName": "John"
},
"content": "This will be unchanged",
"phoneNumber": "+01-123-456-7890",
"tags": [
"example"
],
"title": "Hello!"
}
```
## See also
- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
- [patch](https://json.nlohmann.me/api/basic_json/patch/index.md) apply a JSON patch
- [merge_diff](https://json.nlohmann.me/api/basic_json/merge_diff/index.md) creates a diff as a JSON Merge Patch
## Version history
- Added in version 3.1.0.
- Fixed use of freed or relocated memory when `apply_patch` is `*this` or refers to a value contained in `*this`, in version 3.13.0 unreleased.