Lab 11: JSON Encoding

Time: 30 minutes | Level: Practitioner | Docker: docker run -it --rm golang:1.22-alpine sh

Overview

The encoding/json package handles JSON serialization and deserialization. Struct tags control field names, omission, and custom behaviour. Streaming encoders/decoders handle large data sets without loading everything into memory.

Step 1: Marshal — Struct to JSON

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

type User struct {
    ID        int       `json:"id"`
    Name      string    `json:"name"`
    Email     string    `json:"email,omitempty"` // omit if empty
    CreatedAt time.Time `json:"created_at"`
    Password  string    `json:"-"`               // never marshal
}

func main() {
    u := User{
        ID:        1,
        Name:      "Alice",
        CreatedAt: time.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
        Password:  "secret", // will not appear in JSON
    }

    b, err := json.MarshalIndent(u, "", "  ")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(b))
}

Output:

💡 Tip: omitempty skips zero values: "", 0, false, nil. Tag json:"-" excludes the field entirely.

Step 2: Unmarshal — JSON to Struct

Step 3: Custom MarshalJSON / UnmarshalJSON

Step 4: Streaming with json.Encoder / json.Decoder

Step 5: json.RawMessage — Deferred Parsing

Step 6: json.Number for Precise Numbers

Step 7: Map and Slice JSON

Step 8: Capstone — JSON API Response Builder

📸 Verified Output:

Summary

Feature
Struct Tag / API
Notes

Field name

json:"name"

Lowercase in JSON

Omit if zero

json:"name,omitempty"

Skips "", 0, false, nil

Exclude field

json:"-"

Never serialized

Marshal

json.Marshal(v)

Returns []byte, error

Pretty print

json.MarshalIndent(v, "", " ")

Human-readable

Unmarshal

json.Unmarshal(data, &v)

v must be a pointer

Stream encode

json.NewEncoder(w).Encode(v)

Writes to io.Writer

Stream decode

json.NewDecoder(r).Decode(&v)

Reads from io.Reader

Raw defer

json.RawMessage

Delay parsing of nested object

Big ints

dec.UseNumber() + json.Number

Avoid float64 precision loss

Custom format

MarshalJSON() / UnmarshalJSON()

Implement on type

Last updated