How to add one or more fields when marshalling a struct to JSON in Go

In Go it's easy to omit some fields when marhsalling a struct to JSON with json:"-" but how to add one or more fields to the JSON output?

The easiest and cleanest way to achieve that is by using an anonymous struct when implementing MarshalJSON.

We need to create a separate type (userJson here) as otherwise MarshalJSON will trigger infinite recursion.

main.go

package main

import (
	"encoding/json"
	"fmt"
)

type User struct {
	ID        int64     `json:"id"`
	CreatedAt time.Time `json:"created_at"`

	FirstName string `json:"-"`
	LastName  string `json:"-"`
}


func (user User) MarshalJSON() ([]byte, error) {
	// we use a local type to avoid polluting the package
	type userJson User

	return json.Marshal(struct {
		userJson
		Name string `json:"name"`
	}{
		userJson: userJson(user),
		Name:     user.FirstName + " " + user.LastName,
	})
}

func main() {
	user := User{
		ID:        1,
		CreatedAt: time.Now(),
		FirstName: "Hello",
		LastName:  "World",
	}

	userJson, err := json.MarshalIndent(user, "", "  ")
	if err != nil {
		fmt.Println("Error marshalling user to JSON:", err)
		return
	}

	fmt.Println(string(userJson))
}

Output:

{
  "id": 1,
  "created_at": "2023-01-01T01:01:01.01Z",
  "name": "Hello World"
}
1 email / week to learn how to (ab)use technology for fun & profit: Programming, Hacking & Entrepreneurship.
I hate spam even more than you do. I'll never share your email, and you can unsubscribe at any time.

Tags: golang, programming

Want to learn Rust, Cryptography and Security? Get my book Black Hat Rust!