0
0
GoDebug / FixBeginner · 4 min read

How to Handle Nested JSON in Go: Fix and Best Practices

To handle nested JSON in Go, define Go structs that match the nested structure of the JSON data. Use json.Unmarshal to decode the JSON into these structs, ensuring nested fields are represented as nested structs or slices.
🔍

Why This Happens

When you try to decode nested JSON into a flat Go struct, Go cannot match nested JSON objects to simple fields. This causes errors or missing data because the structure does not align.

go
package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name    string `json:"name"`
	Age     int    `json:"age"`
	Address string `json:"address"` // Incorrect: Address is nested JSON
}

func main() {
	jsonData := `{
		"name": "Alice",
		"age": 30,
		"address": {
			"city": "Wonderland",
			"zip": "12345"
		}
	}`

	var p Person
	err := json.Unmarshal([]byte(jsonData), &p)
	if err != nil {
		fmt.Println("Error:", err)
	}
	fmt.Printf("Person: %+v\n", p)
}
Output
Person: {Name:Alice Age:30 Address:}
🔧

The Fix

Define nested structs to match the JSON structure. For nested objects, create a struct field with its own fields. This lets json.Unmarshal correctly map nested JSON to Go structs.

go
package main

import (
	"encoding/json"
	"fmt"
)

type Address struct {
	City string `json:"city"`
	Zip  string `json:"zip"`
}

type Person struct {
	Name    string  `json:"name"`
	Age     int     `json:"age"`
	Address Address `json:"address"`
}

func main() {
	jsonData := `{
		"name": "Alice",
		"age": 30,
		"address": {
			"city": "Wonderland",
			"zip": "12345"
		}
	}`

	var p Person
	err := json.Unmarshal([]byte(jsonData), &p)
	if err != nil {
		fmt.Println("Error:", err)
	}
	fmt.Printf("Person: %+v\n", p)
}
Output
Person: {Name:Alice Age:30 Address:{City:Wonderland Zip:12345}}
🛡️

Prevention

Always design Go structs to mirror the JSON structure, including nested objects and arrays. Use tools like json-to-go online converters to generate struct templates. Validate JSON structure before decoding and handle errors gracefully.

Use omitempty tags to handle optional fields and pointers for nullable nested objects. Keep your structs updated if JSON changes.

⚠️

Related Errors

Common related errors include:

  • json: cannot unmarshal object into Go struct field - caused by type mismatches or missing nested structs.
  • json: unknown field - when JSON has fields not present in Go structs; use json:"fieldname,omitempty" or json.Decoder.DisallowUnknownFields() carefully.
  • Zero values for nested fields - happens if nested structs are missing or pointers are nil.

Key Takeaways

Match Go structs exactly to the nested JSON structure for successful unmarshalling.
Use nested structs for nested JSON objects to avoid missing or zero values.
Validate JSON and handle errors to catch mismatches early.
Use online tools to generate Go structs from JSON samples.
Keep your struct definitions updated with any changes in JSON format.