Go Structs from JSON: Tags and Types
Go's encoding/json package maps JSON to structs using struct tags. Getting the types and tags right is tedious for large API responses. Here's how the mapping works and how to automate it.
Basic Mapping
The json:"name" tag tells the JSON decoder which JSON key maps to which struct field. Without tags, Go uses the field name directly (case-insensitive matching).
JSON to Go Type Mapping
| JSON Type | Go Type | Notes |
|---|---|---|
"string" | string | |
123 | int | For integers |
1.5 | float64 | All JSON numbers with decimals |
true | bool | |
null | string, int, etc. | Use pointers for nullable fields |
[1,2] | []int | Typed slices |
{} | Nested struct | Or map[string]interface{} for dynamic |
Nested Structs
JSON objects within objects become separate Go structs:
Handling Optional Fields
omitempty
omitempty omits the field from JSON output if it has a zero value:
Pointer types for nullable JSON
If a JSON field can be null, use a pointer:
Without a pointer, null and missing both become the zero value ("" for string), and you can't tell them apart.
Arrays and Slices
JSON arrays become Go slices:
Mixed-type arrays ([1, "two", true]) are uncommon in well-designed APIs but map to []interface{}.
Automated Generation
For large API responses, hand-writing structs is error-prone. Our JSON to Go converter generates complete struct definitions:
- Paste your JSON response
- Get properly tagged Go structs with correct types
- Nested objects are extracted into separate named structs
- Array element types are inferred from the data
Common Patterns
Decoding API responses
Ignoring unknown fields
By default, encoding/json silently ignores JSON keys that don't match any struct field. To enforce strict decoding:
Renaming fields
Go convention is PascalCase, but JSON APIs use camelCase or snake_case. Tags handle the mapping:
Tips
- Always add json tags. Without them, you depend on Go's case-insensitive matching, which is fragile.
- Use pointers for optional fields that you need to distinguish from zero values.
- Generate from real API responses, not docs. The actual response structure is what matters.
- Test with
json.Marshalto verify your struct produces the expected JSON output.