JSON guide · 2 min read
How to Generate Go Structs from JSON
Generate Go structs with JSON tags, then review pointers, number types, optional fields and nested models before unmarshalling real payloads.
Map JSON names with struct tags
Go fields must be exported for encoding/json to populate them. Struct tags preserve external names such as user_id while allowing idiomatic exported Go identifiers.
type User struct {
UserID string `json:"user_id"`
Name string `json:"name"`
}Use pointers when absence matters
A value field receives its zero value when the property is absent. If the application must distinguish missing from explicitly supplied zero, false or empty string, a pointer or another nullable representation can preserve that distinction.
Choose numeric types from documented ranges
JSON has one number grammar while Go has multiple numeric types. An ID that fits in int32 today may exceed it later, and exact financial values should not be modeled casually as binary floating point.
- Use documented ranges for int and int64 decisions.
- Consider json.Number for generic numeric input.
- Keep large non-arithmetic identifiers as strings.
- Use a domain-appropriate decimal representation for exact financial values.
Review null, empty and missing values
JSON null interacts differently with pointers, slices, maps and primitive value fields. Test the payload variations your API actually produces instead of assuming one generated shape covers them.
Rename nested types for the domain
Generators often create mechanical type names from paths. Rename reusable structs to meaningful domain names so the generated result becomes maintainable application code rather than a one-off translation.
Unmarshal production-like variants
Test missing fields, nulls, empty arrays, large numbers and unknown properties with the same decoder options used by the application. Generation saves typing; testing confirms the model actually fits the contract.
var user User
if err := json.Unmarshal(payload, &user); err != nil {
return fmt.Errorf("decode user: %w", err)
}Common questions
Frequently asked questions
Why use pointers in generated Go structs?
Pointers can distinguish an absent or null value from a type's zero value when that distinction matters.
Can JSON numbers overflow Go fields?
Yes. Choose numeric types from documented ranges and consider strings or json.Number for uncertain or very large values.
Will encoding/json reject unknown fields by default?
No. Use Decoder.DisallowUnknownFields when the boundary should reject properties that are not declared by the struct.