Skip to content

JSON in Go

Go makes it incredibly easy to work with JSON using the encoding/json package.

1. Marshalling (Go to JSON)

Converting a Go struct or map into a JSON string.

package main

import (
    "encoding/json"
    "fmt"
)

type Response struct {
    Page   int      `json:"page"`
    Fruits []string `json:"fruits"`
}

func main() {
    res := Response{
        Page:   1,
        Fruits: []string{"apple", "peach", "pear"},
    }

    // Convert to JSON bytes
    bytes, _ := json.Marshal(res)
    fmt.Println(string(bytes)) // {"page":1,"fruits":["apple","peach","pear"]}

    // Pretty print version
    pretty, _ := json.MarshalIndent(res, "", "  ")
    fmt.Println(string(pretty))
}

2. Unmarshalling (JSON to Go)

Converting a JSON string back into a Go struct.

1
2
3
4
5
6
7
str := `{"page": 1, "fruits": ["apple", "peach"]}`
res := Response{}

// Use a pointer so Unmarshal can modify the struct
json.Unmarshal([]byte(str), &res)

fmt.Println(res.Page) // 1

3. Maps for Dynamic JSON

If you don't know the keys in advance, use a map.

1
2
3
4
5
str := `{"apple": 5, "lettuce": 7}`
var data map[string]int

json.Unmarshal([]byte(str), &data)
fmt.Println(data["apple"]) // 5

4. Struct Tags

Struct tags (the text in backticks) tell the JSON package how to name the fields in the output.

  • json:"name": Use "name" instead of the Go variable name.
  • json:"-": Ignore this field completely.
  • json:"id,omitempty": Don't include this field if it's empty (0, "", nil).

Using Encoder and Decoder

If you are reading from a network connection or a file, use Encoder and Decoder as they work directly with streams.

// Writing directly to standard out
json.NewEncoder(os.Stdout).Encode(res)