SyntaxStudy
Sign Up
Go Struct Tags and JSON Serialisation
Go Beginner 1 min read

Struct Tags and JSON Serialisation

Struct tags are string literals attached to struct fields that provide metadata consumed by packages at runtime via reflection. The most common use is with `encoding/json`, where tags control how fields are serialised and deserialised. A tag of the form `json:"name,omitempty"` maps the Go field to a JSON key and omits it when the value is the zero value. The `encoding/json` package uses reflection to inspect struct tags at runtime. `json.Marshal` converts a Go value to JSON bytes, and `json.Unmarshal` parses JSON bytes into a Go value. Fields that start with a lowercase letter are unexported and are ignored by the JSON encoder, so all fields intended for serialisation must start with an uppercase letter. Beyond JSON, struct tags are used by database packages (e.g., `db:` for sqlx), validation libraries (e.g., `validate:`), and ORM frameworks. The tag format is space-separated key-value pairs where each value is a quoted string, and the entire tag is a raw string literal in backticks.
Example
package main

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

type Address struct {
    Street string `json:"street"`
    City   string `json:"city"`
    Zip    string `json:"zip,omitempty"`
}

type User struct {
    ID        int       `json:"id"`
    Username  string    `json:"username"`
    Email     string    `json:"email"`
    Password  string    `json:"-"`           // never serialised
    Address   Address   `json:"address"`
    CreatedAt time.Time `json:"created_at"`
    Score     *float64  `json:"score,omitempty"`
}

func main() {
    u := User{
        ID:        1,
        Username:  "gopher",
        Email:     "gopher@example.com",
        Password:  "secret",
        Address:   Address{Street: "1 Main St", City: "Springfield"},
        CreatedAt: time.Now(),
    }

    // Marshal to JSON
    data, err := json.MarshalIndent(u, "", "  ")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(data))

    // Unmarshal from JSON
    raw := `{"id":2,"username":"alice","email":"alice@example.com","address":{"street":"2 Elm St","city":"Shelbyville","zip":"12345"},"created_at":"2024-01-01T00:00:00Z"}`
    var u2 User
    if err := json.Unmarshal([]byte(raw), &u2); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Decoded: %+v\n", u2)
}