Json Patch and Json Merge Patch both do one job well - a way to represent a change to a source json structure.
Json Patch does it as a series of operations which transforms a source document and Json Merge Patch represents the change as a lite version of the source document.
It is easier to show these as an example, and this is straight from the Json Merge Patch's RFC.
Let's start with a source document:
{ "title": "Goodbye!", "author": { "givenName": "John", "familyName": "Doe" }, "tags": [ "example", "sample" ], "content": "This will be unchanged" }and the objective is to transform it to this document:
{ "title": "Hello!", "author": { "givenName": "John" }, "tags": [ "example" ], "content": "This will be unchanged", "phoneNumber": "+01-123-456-7890" }Which may be easier to visualize in a diff view:
- The title is being changed
- Author/familyName is removed
- One of the tags is removed
- A phone number is added
Json Patch
This change can be represented the following way using Json Patch document:[ { "op": "replace", "path": "/title", "value": "Hello!"}, { "op": "remove", "path": "/author/familyName"}, { "op": "add", "path": "/phoneNumber", "value": "+01-123-456-7890"}, { "op": "replace", "path": "/tags", "value": ["example"]} ]A series of operations transforms the source document into the target document. An operation can be one of "add", "remove", "replace", "move", "copy" or "test" and in the example exactly matches the diff.
Json Merge Patch
A Json merge patch for the change looks like this:{ "title": "Hello!", "author": { "familyName": null }, "phoneNumber": "+01-123-456-7890", "tags": [ "example" ] }There is a little bit of interpretation required on how the change gets applied, it is very intuitive though: 1. The presence of "title" with a new value indicates that the title needs to be changed. 2. An explicit "null" for the family name indicates that the field should be removed 3. A phoneNumber field indicates that a new field needs to be added 4. Updated tags indicates that the tags need to be modified.
Using Json Patch with Java
json-patch is an awesome java library that provides support for both Json Patch and Json Merge Patch. It integrates with the excellent Jackson library and provides patch tooling on top of the the library. The sample is in kotlin:val s = """ { "title": "Goodbye!", "author": { "givenName": "John", "familyName": "Doe" }, "tags": [ "example", "sample" ], "content": "This will be unchanged" } """.trimIndent() val patch = """ [ { "op": "replace", "path": "/title", "value": "Hello!"}, { "op": "remove", "path": "/author/familyName"}, { "op": "add", "path": "/phoneNumber", "value": "+01-123-456-7890"}, { "op": "replace", "path": "/tags", "value": ["example"]} ] """.trimIndent() val jsonPatch: JsonPatch = JsonPatch.fromJson(objectMapper.readTree(patch)) val target = jsonPatch.apply(objectMapper.readTree(s))
Using Json Merge Patch with Java
The library makes using Json Merge patch equally easy:val s = """ { "title": "Goodbye!", "author": { "givenName": "John", "familyName": "Doe" }, "tags": [ "example", "sample" ], "content": "This will be unchanged" } """.trimIndent() val patch = """ { "title": "Hello!", "author": { "familyName": null }, "phoneNumber": "+01-123-456-7890", "tags": ["example"] } """.trimIndent() val jsonMergePatch: JsonMergePatch = JsonMergePatch.fromJson(objectMapper.readTree(patch)) val target = jsonMergePatch.apply(objectMapper.readTree(s))
The title is “Json Patch and Json Merge Patch in Java” and the whole contents make mention only of Java, no Kotlin, but the sample codes are of Kotlin.
ReplyDeleteYes, fair point. I see kotlin and java as completely interchangeable that is the reason why the title says Java but I have used a Kotlin sample.
DeleteYes. They are interchangeable but still Java is Java and Kotlin is Kotlin.
Delete