{ "title": "Goodbye!", "author": { "givenName": "John", "familyName": "Doe" }, "tags": [ "example", "sample" ], "content": "This will be unchanged" }A kotlin representation of this entity is the following:
data class Book( val title: String, val author: Author, val tags: List<String>, val content: String, val phoneNumber: String? = null ) data class Author( val givenName: String, val familyName: String? = null )Let's start with an endpoint that performs a Json Patch The endpoint should accept the patch in a request body, should accept a content type of "application/json-patch+json": A sample kotlin code of such an endpoint is the following:
import com.github.fge.jsonpatch.JsonPatch ... ... @PatchMapping(path = ["/{id}"], consumes = ["application/json-patch+json"]) fun jsonPatchBook( @PathVariable id: String, @RequestBody patch: JsonNode ): Mono<ResponseEntity<Book>> { return Mono.fromSupplier { val jsonPatch: JsonPatch = JsonPatch.fromJson(patch) val original: JsonNode = objectMapper.valueToTree(getBook(id)) val patched: JsonNode = jsonPatch.apply(original) val patchedBook: Book = objectMapper.treeToValue(patched) ?: throw RuntimeException("Could not convert json back to book") updateBook(patchedBook) ResponseEntity.ok(patchedBook) } }All that is involved is to :
- Take in the Json Patch body and convert it into the JsonPatch type
- Retrieve the Book entity for the identifier
- Convert the Book entity into a Json representation
- Apply the patch and convert the resulting json back into the Book entity
For an endpoint that performs Json Merge patch, along the same lines, the endpoint should accept the json merge patch request body with a content type of "application/merge-patch+json":
@PatchMapping(path = ["/{id}"], consumes = ["application/merge-patch+json"]) fun jsonMergePatchBook( @PathVariable id: String, @RequestBody patch: JsonNode ): Mono<ResponseEntity<Book>> { return Mono.fromSupplier { val original: JsonNode = objectMapper.valueToTree(getBook(id)) val patched: JsonNode = JsonMergePatch.fromJson(patch).apply(original) val patchedBook: Book = objectMapper.treeToValue(patched) ?: throw RuntimeException("Could not convert json back to book") updateBook(patchedBook) ResponseEntity.ok(patchedBook) } }Steps are:
- Take in the Json Merge Patch body
- Retrieve the Book entity for the identifier
- Convert the Book entity into a Json representation
- Apply the merge patch and convert the resulting json back into the Book entity