How to Handle Dynamic JSON in Go: Simple Fix and Tips
interface{} to unmarshal the data into a generic structure like map[string]interface{}. Then use type assertions to access nested values safely, since Go needs explicit types for dynamic content.Why This Happens
Go is a statically typed language, so it expects JSON data to match a predefined structure. When JSON contains dynamic or unknown fields, unmarshaling directly into a struct causes errors or missing data because Go doesn't know how to map unknown keys.
package main import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name"` Age int `json:"age"` } func main() { jsonData := []byte(`{"name":"Alice","age":30,"city":"Wonderland"}`) var p Person err := json.Unmarshal(jsonData, &p) if err != nil { fmt.Println("Error:", err) return } fmt.Printf("Person: %+v\n", p) }
The Fix
Use map[string]interface{} to unmarshal dynamic JSON. This lets Go store any JSON key-value pairs without a fixed struct. Then use type assertions to extract values safely.
package main import ( "encoding/json" "fmt" ) func main() { jsonData := []byte(`{"name":"Alice","age":30,"city":"Wonderland"}`) var data map[string]interface{} err := json.Unmarshal(jsonData, &data) if err != nil { fmt.Println("Error:", err) return } fmt.Println("Name:", data["name"]) fmt.Println("Age:", data["age"]) // Use type assertion to get string value if city, ok := data["city"].(string); ok { fmt.Println("City:", city) } else { fmt.Println("City not found or not a string") } }
Prevention
To avoid issues with dynamic JSON, always unmarshal into map[string]interface{} or use interface{} when the structure is unknown or varies. Use type assertions carefully to check types before using values. Consider using libraries like github.com/mitchellh/mapstructure for easier decoding.
Also, validate JSON schema if possible before unmarshaling to catch unexpected formats early.
Related Errors
Common related errors include:
- json: cannot unmarshal object into Go struct field - caused by mismatched JSON and struct fields.
- interface conversion: interface {} is float64, not string - happens when type assertions are incorrect.
Fix these by using map[string]interface{} and checking types before use.