Direct naar de hoofdinhoud
Module 8 · Les 5 van 540/50 in de cursus~14 min
Modulelessen (5/5)

`codering/json`

encoding/json is het canonieke pakket voor het serialiseren van Go-structuren naar JSON en terug. Als u de conventies en valkuilen kent, bespaart u urenlang debuggen van API's en configuratiebestanden.

Maarschalk en Unmaarschalk

De twee belangrijkste functies:

Go
data, err := json.Marshal(v)      // Go → []byte JSON
err = json.Unmarshal(data, &v)    // JSON → Go (pass a pointer!)
Go
type User struct {
    Name  string
    Email string
}

u := User{Name: "Ada", Email: "ada@example.com"}
b, _ := json.Marshal(u)
fmt.Println(string(b))
// {"Name":"Ada","Email":"ada@example.com"}

var back User
_ = json.Unmarshal(b, &back)

Voor ingesprongen uitvoer (voor mensen leesbaar) gebruikt u json.MarshalIndent(v, "", " ").

Alleen geëxporteerde velden

json.Marshal serialiseert alleen geëxporteerde velden (hoofdletters). Privévelden worden stil genegeerd:

Go
type U struct {
    Name string // exported → serialized
    age  int    // private → ignored
}

Structure-tags: controle over naam en opties

De json:"..." tags bepalen de naam, weglatingen en typen in de uitvoer:

Go
type User struct {
    Name    string `json:"name"`                    // rename
    Email   string `json:"email,omitempty"`         // omit if zero value
    Private string `json:"-"`                       // never serialized
    ID      int    `json:"id,string"`               // number as string
}

Meest gebruikte opties:

  • ,omitempty — laat het veld weg als het de nulwaarde is (0, "", nul, leeg segment/kaart).
  • ,- — nooit geserialiseerd/gedeserialiseerd.
  • ,string — verpakt getallen/bools als tekenreeksen (handig voor JS-ID's).

Decoder/Encoder voor streams

Wanneer u werkt met io.Reader/io.Writer (HTTP-body, grote bestanden), gebruikt u Decoder en Encoder in plaats van alles in het geheugen te laden:

Go
dec := json.NewDecoder(resp.Body)
var users []User
if err := dec.Decode(&users); err != nil {
    return err
}

enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", "  ")
_ = enc.Encode(users)

Decoder ondersteunt ook dec.Token() voor het stuk voor stuk parseren van streaming en dec.DisallowUnknownFields() om JSON met onverwachte sleutels te weigeren (handig voor invoervalidatie).

Algemene kaarten en any

Als u het schema niet kent, deserialiseer dan naar map[string]any:

Go
var v map[string]any
_ = json.Unmarshal(data, &v)
fmt.Println(v["name"])

Waarden hebben dynamische typen (string, float64 voor getallen, []any, map[string]any, bool, nil).

Veelvoorkomende fouten

  • Vergeten &: json.Unmarshal(data, v) vult niets in; je hebt &v nodig.
  • Decodering van structuren met nul velden: om paniek te voorkomen, controleer err VOORDAT u velden leest.
  • Incompatibele typen: het deserialiseren van een getal in een tekenreeks of omgekeerd retourneert *json.UnmarshalTypeError.

Oefeningen

Oefening#go.m8.l5.e1
Pogingen: 0Laden…

Serialiseer de struct u naar JSON met json.Marshal en druk het resultaat af als een tekenreeks.

Editor laden…

Oplossing beschikbaar na 3 pogingen

Oefening#go.m8.l5.e2
Pogingen: 0Laden…

Deserialiseer `{"Name":Ada"}` in de struct U met json.Unmarshal en druk het af.

Editor laden…

Oplossing beschikbaar na 3 pogingen

Quiz#go.m8.l5.e3
Klaar

Is het veld `name string` (kleine letters) van een struct opgenomen door json.Marshal?

Go
type U struct {
  name string
}
b, _ := json.Marshal(U{name: "Ada"})
fmt.Println(string(b))
Antwoordmogelijkheden