Skip to main content

JSON Patch

JSON Patch (RFC 6902) is a standard for describing update operations to perform on JSON-like data. Each operation includes, at least, an op string and a path, which is a JSON Pointer.

Use jsonpatch.apply(ops, data) to apply ops to data, where ops should be an array of OpObjects, as per RFC 6902. Patch operation are applied sequentially and, unless the target JSON document's root value is replaced, data is modified in place.

import { jsonpatch } from "json-p3";

const ops = [
{ op: "add", path: "/some/foo", value: { foo: {} } },
{ op: "add", path: "/some/foo", value: { bar: [] } },
{ op: "copy", from: "/some/other", path: "/some/foo/else" },
{ op: "add", path: "/some/foo/bar/-", value: 1 },
];

const data = { some: { other: "thing" } };
jsonpatch.apply(ops, data);
console.log(data);
// { some: { other: 'thing', foo: { bar: [Array], else: 'thing' } } }

Use the JSONPatch constructor to create a patch for repeated application.

import { JSONPatch } from "json-p3";

const patch = new JSONPatch([
{ op: "add", path: "/some/foo", value: { foo: {} } },
{ op: "add", path: "/some/foo", value: { bar: [] } },
{ op: "copy", from: "/some/other", path: "/some/foo/else" },
{ op: "add", path: "/some/foo/bar/-", value: 1 },
]);

const data = { some: { other: "thing" } };
patch.apply(data);
console.log(data);
// { some: { other: 'thing', foo: { bar: [Array], else: 'thing' } } }

Builder API

JSONPatch implements a builder interface for constructing JSON Patch documents. Each of the following methods appends an operation to the patch and returns the patch instance, so method calls can be chained.

add()

JSONPatch.add(pointer, value) appends an add operation to the patch. pointer can be a string following RFC 6901 or an instance of JSONPointer.

import { JSONPatch } from "json-p3";

const patch = new JSONPatch().add("/some/foo", { foo: [] });
console.log(JSON.stringify(patch.toArray(), undefined, " "));
output
[
{
"op": "add",
"path": "/some/foo",
"value": {
"foo": []
}
}
]

remove()

JSONPatch.remove(pointer) appends an remove operation to the patch. pointer can be a string following RFC 6901 or an instance of JSONPointer.

import { JSONPatch } from "json-p3";

const patch = new JSONPatch().remove("/some/foo");
console.log(JSON.stringify(patch.toArray(), undefined, " "));
output
[
{
"op": "remove",
"path": "/some/foo"
}
]

replace()

JSONPatch.replace(pointer, value) appends an replace operation to the patch. pointer can be a string following RFC 6901 or an instance of JSONPointer.

import { JSONPatch } from "json-p3";

const patch = new JSONPatch().replace("/some/foo", [1, 2, 3]);
console.log(JSON.stringify(patch.toArray(), undefined, " "));
output
[
{
"op": "replace",
"path": "/some/foo",
"value": [1, 2, 3]
}
]

move()

JSONPatch.move(fromPointer, toPointer) appends an move operation to the patch. fromPointer and toPointer can be a string following RFC 6901 or an instance of JSONPointer.

import { JSONPatch } from "json-p3";

const patch = new JSONPatch().move("/some/foo", "/other/bar");
console.log(JSON.stringify(patch.toArray(), undefined, " "));
output
[
{
"op": "move",
"from": "/some/foo",
"path": "/other/bar"
}
]

copy()

JSONPatch.copy(fromPointer, toPointer) appends an copy operation to the patch. fromPointer and toPointer can be a string following RFC 6901 or an instance of JSONPointer.

import { JSONPatch } from "json-p3";

const patch = new JSONPatch().copy("/some/foo", "/other/bar");
console.log(JSON.stringify(patch.toArray(), undefined, " "));
output
[
{
"op": "copy",
"from": "/some/foo",
"path": "/other/bar"
}
]

test()

JSONPatch.copy(pointer, value) appends an test operation to the patch. pointer can be a string following RFC 6901 or an instance of JSONPointer.

import { JSONPatch } from "json-p3";

const patch = new JSONPatch().test("/some/foo", "hello");
console.log(JSON.stringify(patch.toArray(), undefined, " "));
output
[
{
"op": "test",
"path": "/some/foo",
"value": "hello"
}
]