Creating a JSON Patch endpoint in Go

Featured image for sharing metadata for article

JSON Patch is a well-defined format for performing updates to HTTP objects, which allows you to avoid needing to design your own means for performing partial changes.

As I've been recently looking at setting up a Go API with JSON Patch, I wanted to explore options for making this more straightforward.

Fortunately, evanphx/json-patch makes it a breeze, allowing us to convert the request body into a JSON patch object, and then we can apply it to our object.

Inside our HTTP handler, we can

func AccountsPatchHandler(w http.ResponseWriter, r *http.Request) {
	// ...

	body, err := io.ReadAll(r.Body)
	// handle err

	patch, err := jsonpatch.DecodePatch(body)
	// handle err

	// this would be retrieved by i.e. a Service or Repository tier object
	domainModel := Account{
		ID:    "1",
		Email: "example@example.com",
	}

	// then we map it into the type that's expected by our HTTP consumers
	current := AccountRepresenation{
		ID:    domainModel.ID,
		Email: domainModel.Email,
	}

	// marshal it to JSON, to be able to the patch
	currentBytes, err := json.Marshal(current)
	// handle err

	modifiedBytes, err := patch.Apply(currentBytes)
	if err != nil {
		w.Write([]byte(err.Error()))
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	var modified AccountRepresenation
	err = json.Unmarshal(modifiedBytes, &modified)
	// handle err

	// perform business logic checks
	if modified.ID != current.ID {
		w.WriteHeader(http.StatusUnprocessableEntity)
		w.Write([]byte("The ID field cannot be modified"))
		return
	}

	// we'd then usually persist the data here
	// but in this example, we don't have a way to

	// and we need to make sure that when returning the re-marshalled model, as if we return `modifiedBytes`, we could end up with unsupported fields being returned
	outBytes, err := json.Marshal(modified)
	_, _ = w.Write(outBytes)

This makes it quite convenient to be able to perform the patch, meaning we simply need to handle any business logic around the updates, and converting between data types.

The full code can be found in a repo on GitLab.

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #api #json-patch.

Also on:

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.