In Go wordt JSON-marshalling standaard geïmplementeerd via het pakket encoding/json. Alleen geëxporteerde (met een hoofdletter) velden van structuren kunnen worden geserialiseerd. Voor het beheren van namen en verwerking worden struct-tags gebruikt:
type User struct { ID int `json:"id"` Name string `json:"name,omitempty"` Age int `json:"age,string"` }
omitempty sluit het veld uit bij een nulwaarde;string serialiseert de waarde als een string, zelfs als dit een getal is.user := User{ID: 1, Name: "Oleg"} b, _ := json.Marshal(user) fmt.Println(string(b)) // {"id":1,"name":"Oleg","age":"0"}
var u User json.Unmarshal([]byte('{"id":2,"name":"Ivan"}'), &u)
Hoe worden niet-geëxporteerde (met een kleine letter) velden van een structuur geserialiseerd tijdens het marshalling naar JSON?
Juiste antwoord: Ze worden genegeerd, alleen geëxporteerde (met een hoofdletter) velden worden in de serilisatie opgenomen. Dit breekt vaak plotseling de API:
type Foo struct { bar int // zal niet worden geserialiseerd! }
Verhaal
De backend genereerde onvolledige JSON-objecten, omdat een deel van de benodigde velden niet-geëxporteerd (met een kleine letter) was. Het kostte meerdere dagen om uit te vinden waarom klanten deze velden niet konden zien.
Verhaal
In het API-antwoord zat een omitempty constructie, maar soms kwam er een lege waarde binnen, omdat de nulwaarde voor een slice nil is en niet een lege slice. Klanten ontvingen null in plaats van een lege array [] en faalden tijdens parsing.
Verhaal
In het project werden dynamische velden aan structuren toegevoegd via map[string]interface{}, maar we vergaten om een aangepaste UnmarshalJSON te implementeren, waardoor een deel van de gegevens "verdween" zonder fouten. Klantgegevens gingen verloren en moesten handmatig worden hersteld uit back-ups.