Creating RFC6902 JSON Patches in GoLang With HTTP PATCH Method
Introduction
HTTP is the widely used protocol for fetching resources over the web. It’s the building block for any data exchange that happens over the world wide web. Several applications that use HTTP protocol for accessing and storing resources needs a feature to partially modify the resources.
HTTP supports a PUT
method that does a complete replacement of the resource. It overrides the resource with a completely new body and cannot be re-purposed for partial modification of resources.
In this article, we will learn how to apply a JSON patch to the existing resource in conjunction with the HTTP PATCH
method in GoLang.
Concept
The JSON patch document can be used to partially update a resource. For instance, if you only need to modify one field of the resource, sending the entire new resource with just one field modified is not going to be a good option.
Considering we are going to make a remote call, PUT
ting a complete resource representation is going to utilize more bandwidth and might be a cumbersome job.
JSON PATCH document
JSON Patch is a format for describing changes to a JSON document. It can be used to avoid sending a whole document when only a part has changed. The PATCH document is itself a JSON document.
When used in combination with the HTTP PATCH method, it allows partial updates for HTTP APIs in a standards compliant way.
Sample JSON patch document.
[ {"op": "replace", "path": "/foo", "value": "Hello"}, {"op": "remove", "path": "/phi"}]
We specify the operation as op
, the field which needs to be updated as path
and the new value using value
. The above keywords are compliant with the RFC6902 standard. This is just a sample JSON document. Refer to JavaScript Object Notation (JSON) Patch for a detailed list.
PUT vs PATCH method
Here are a few key differences between HTTP PUT
and PATCH
method.
- PUT contain a “new representation” of a resource, while PATCH contains “a set of changes” to a resource.
- PUT is idempotent while PATCH is non-idempotent.
- PUT ensures safe updates to resources, while PATCH is not safe to update, we need to make sure the PATCH operation is atomic, to avoid producing partially patched resources.
Setup
We are going to use Go’s jsonpatch
library for creating and merging JSON patches.
go get -v github.com/evanphx/json-patch/v5
Using mux
library in Golang for creating the endpoints.
go get -v github.com/gorilla/mux
Implementation
We will cover two ways of updating a resource:
- Update using the JSON PATCH Document.
- Update by merging the PATCH JSON with the original JSON.
Essentially, it means either we can pass a JSON patch document that will have the instructions for updating the resource as part of an HTTP request or we can send the patched JSON directly as part of the request which can be directly merged with the original JSON.
Update using the JSON PATCH Document
We send the instructions for updating a resource as part of the request in the form JSON patch document. It involves decoding the JSON patch document and applying it to the original JSON.
Let’s define a Model
which can be used for storing the data. Consider a simple scenario where we want to maintain the records of all movies which are released worldwide. The model will have the following fields.
We define additional JSON tags with each field json:"key,omitempty"
. The tag key will be used as field name while Marshalling the object to JSON, omitempty
avoids empty fields from marshaling to JSON.
We expect the rest of the fields to remain the same while gross
can change with time. Let’s create a JSON patch document for updating the gross
value and also get rid of the releasedOn
field from the final JSON.
[ {"op": "replace", "path": "/gross", "value": "$3.03B"}, {"op": "remove", "path": "/releasedOn"}]
Let’s initialize the Movie
object. We will set the initial gross
value to $2.768B. applyPatch
method will extract the PATCH document from the request, decode the instruction, and apply it to the original JSON.
Let’s make a request to the patch
endpoint, we expect the value of gross
to change to $3.03B and the field releasedOn
to be removed from the original JSON.
Here’s the POSTMAN call to the service.
Update by merging the PATCH JSON with the original JSON
Let’s implement another way of achieving the same. But, this time instead of passing the instructions, we are going to pass the patched JSON that can be merged with the original JSON. I personally prefer this way as it helps us to avoid knowing the available instructions with RFC6902 standards. We can simply pass the resource fields that need to be updated as part of the request and can merge this with the original JSON.
Let’s make a service call to the merge
endpoint with the following request body.
{ "name": "Avengers End Game", "gross": "$4.09B"}
We expect the gross
to be changed to $4.09B.
Routes
Let’s configure the routes for calling the endpoints.
Finally
Here’s the complete code. Do give it a try!!
Thank You So Much!!!
I hope you found this article helpful. Thanks for taking out time to read it.
Happy Coding!!! 😍