skip to content
Alvin Lucillo

Overriding JSON marshalling

/ 1 min read

In the example below, marshalled struct did not follow the struct shape because we override the marshalling process by defining MarshalJSON(). When we call json.Marshal(), the package checks if the value implements Marshaller, which defines MarshalJSON(). Inside the custom MarshalJSON, we define another struct, Alias, to transform the final shape of the marshalled value.

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name string
	Age  int
}

// MarshalJSON overrides default JSON marshaling
func (p Person) MarshalJSON() ([]byte, error) {
	// Create an anonymous struct for custom output
	type Alias struct {
		Name    string `json:"name"`
		IsAdult bool   `json:"is_adult"`
	}

	return json.Marshal(Alias{
		Name:    p.Name,
		IsAdult: p.Age >= 18, // derived field
	})
}

func main() {
	p := Person{
		Name: "alice",
		Age:  20,
	}

	data, err := json.Marshal(p)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(data)) // {"name":"alice","is_adult":true}
}