So blenden Sie Strukturfelder in JSON aus: Go für Anfänger und Profis

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Die Magie von JSON in Go: Warum sind manche Felder sichtbar und andere nicht?

\n

Haben Sie jemals erlebt, dass Ihre Go-Struktur etwas in der JSON-Antwort sendet, das der Client nicht sehen muss? Zum Beispiel ein Benutzerpasswort, eine interne Datenbank-ID oder einen geheimen Schlüssel. Oder umgekehrt: Sie müssen ein Feld nur unter bestimmten Bedingungen anzeigen (z. B. wenn es nicht leer ist).

\n

Dieses Problem ist eines der beliebtesten auf Stack Overflow, und das aus gutem Grund. Die Arbeit mit JSON in Go ist eine Kunst, Typenstrenge mit Darstellungsflexibilität in Einklang zu bringen. Heute behandeln wir alle Methoden: vom einfachen json:"-"-Tag bis hin zu komplexen benutzerdefinierten Lösungen mit Schnittstellen. Los geht's!

\n\n

1. Der einfachste Weg: Das json:"-"-Tag

\n

Go ermöglicht es Ihnen, die Strukturserialisierung durch spezielle Tags zu steuern. Wenn Sie ein Feld dauerhaft vor JSON verstecken möchten, fügen Sie einfach json:"-" hinzu.

\n
type User struct {\n    Name     string `json:"name"`\n    Password string `json:"-"`\n    Age      int    `json:"age"`\n}\n\nfunc main() {\n    u := User{Name: "Alice", Password: "supersecret", Age: 30}\n    data, _ := json.Marshal(u)\n    fmt.Println(string(data))\n    // Ausgabe: {"name":"Alice","age":30}\n}
\n

Das Feld Password ist verschwunden, als hätte es nie existiert. Perfekt für vertrauliche Daten, die den Server niemals verlassen sollten.

\n\n

2. Bedingtes Ausblenden: omitempty

\n

Manchmal müssen Sie ein Feld nur ausblenden, wenn es leer ist. Dafür wird die Option omitempty verwendet (kurz für "weglassen, wenn leer").

\n
type Product struct {\n    Name        string  `json:"name"`\n    Description string  `json:"description,omitempty"`\n    Price       float64 `json:"price,omitempty"`\n}\n\nfunc main() {\n    p1 := Product{Name: "Buch", Price: 500.0}\n    data1, _ := json.Marshal(p1)\n    fmt.Println(string(data1)) // {"name":"Buch","price":500}\n\n    p2 := Product{Name: "Kurs"}\n    data2, _ := json.Marshal(p2)\n    fmt.Println(string(data2)) // {"name":"Kurs"}\n}
\n

Wichtig: omitempty funktioniert nur mit "Null"-Werten: "", 0, false, nil (für Slices, Maps, Zeiger).

\n\n

Falle bei numerischen Feldern

\n

Seien Sie vorsichtig: Wenn Price gleich 0 ist, wird es ebenfalls ausgeblendet. In mancher Geschäftslogik ist das inakzeptabel (ein kostenloses Produkt ist trotzdem ein Preis). In solchen Fällen ist es besser, Zeiger zu verwenden.

\n\n

3. Verwendung von Zeigern (*) und Schnittstellen

\n

Zeiger sind Ihr bester Freund, wenn Sie zwischen "Wert nicht angegeben" und "Wert gleich Null" unterscheiden müssen.

\n
type UserProfile struct {\n    Name    string  `json:"name"`\n    Age     *int    `json:"age,omitempty"`  // Zeiger auf int\n    Bio     *string `json:"bio,omitempty"`\n}\n\nfunc main() {\n    // Alter nicht angegeben — Feld wird ausgeblendet\n    u1 := UserProfile{Name: "Ivan"}\n    data1, _ := json.Marshal(u1)\n    fmt.Println(string(data1)) // {"name":"Ivan"}\n\n    // Alter = 0 — dies ist ein sinnvoller Wert\n    zero := 0\n    u2 := UserProfile{Name: "Maria", Age: &zero}\n    data2, _ := json.Marshal(u2)\n    fmt.Println(string(data2)) // {"name":"Maria","age":0}\n}
\n

Dieser Ansatz wird häufig in REST-APIs verwendet, wenn Sie nur die übergebenen Felder aktualisieren müssen (partielle Updates, PATCH-Anfragen).

\n\n

4. Benutzerdefinierte Serialisierung: Die json.Marshaler-Schnittstelle

\n

Wenn Standard-Tags nicht ausreichen, können Sie den Prozess vollständig steuern. Implementieren Sie die json.Marshaler-Schnittstelle und schreiben Sie Ihre eigene Logik.

\n
type DynamicUser struct {\n    ID        int\n    Name      string\n    ShowEmail bool\n    Email     string\n}\n\nfunc (u DynamicUser) MarshalJSON() ([]byte, error) {\n    // Erstellen Sie eine anonyme Struktur nur für die Serialisierung\n    m := map[string]interface{}{\n        "id":   u.ID,\n        "name": u.Name,\n    }\n    if u.ShowEmail {

Blogs

Buchempfehlungen