In Go wird das JSON-Marshaling standardmäßig über das Paket encoding/json implementiert. Es können nur exportierte (mit großem Anfangsbuchstaben) Felder von Strukturen serialisiert werden. Zur Steuerung der Namen und Verarbeitung werden Struct-Tags verwendet:
type User struct { ID int `json:"id"` Name string `json:"name,omitempty"` Age int `json:"age,string"` }
omitempty schließt das Feld bei einem Nullwert aus;string serialisiert den Wert als Zeichenkette, selbst wenn es eine Zahl ist.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)
Wie werden nicht exportierte (mit kleinem Anfangsbuchstaben) Felder von Strukturen beim Marshaling in JSON serialisiert?
Richtige Antwort: Sie werden ignoriert, bei der Serialisierung werden nur exportierte (mit großem Anfangsbuchstaben) Felder einbezogen. Dies kann API unerwartet brechen:
type Foo struct { bar int // wird nicht serialisiert! }
Geschichte
Das Backend lieferte unvollständige JSON-Objekte, weil einige erforderliche Felder nicht exportiert waren (mit kleinem Anfangsbuchstaben). Es dauerte mehrere Tage, um herauszufinden, warum die Clients diese Felder nicht sehen konnten.
Geschichte
Im API-Antwortfeld war die Konstruktion omitempty enthalten, aber manchmal kam ein leerer Wert zurück, weil der Nullwert für einen Slice nil ist und nicht ein leerer Slice. Die Clients erhielten null anstelle eines leeren Arrays [] und stürzten beim Parsen ab.
Geschichte
Im Projekt wurden dynamische Felder zu Strukturen über map[string]interface hinzugefügt, aber es wurde vergessen, ein benutzerdefiniertes UnmarshalJSON zu implementieren, wodurch ein Teil der Daten ohne Fehler "verloren" ging. Kundendaten gingen verloren und mussten manuell aus Backups wiederhergestellt werden.