Creating RFC6902 JSON Patches in GoLang With HTTP PATCH Method

Chetan Mehta
The Startup
Published in
5 min readSep 6, 2020
“You’re a Good man, with Good Heart. It’s hard for a Good Man to be the King.” — T’Chakka

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, PUTting 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.

  1. PUT contain a “new representation” of a resource, while PATCH contains “a set of changes” to a resource.
  2. PUT is idempotent while PATCH is non-idempotent.
  3. 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.
“Just because something doesn’t do what you planned it to do doesn’t mean it’s useless. “ — Thomas Edison

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:

  1. Update using the JSON PATCH Document.
  2. 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.

“The desire to create is one of the deepest yearnings of the human soul.” — Dieter F. Uchtdorf

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.

“Nature is pleased with simplicity. And nature is no dummy.” — Isaac Newton

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!!! 😍

--

--

Chetan Mehta
The Startup

To err is human… to really foul up requires the root password.