← Back to Go Course | Chapter 14: Standard Library & HTTP | Lesson 6 of 10

JSON Encoding with encoding/json

encoding/json is Go's translator between structs (Go's own data shapes) and JSON text, the common format used to send data between different programs.

Marshaling a Struct to JSON

json.Marshal converts a Go value -- most commonly a struct -- into its JSON representation as a byte slice, using each exported field's name (or its json tag, if present) as the key.

Example: Marshaling a Struct to JSON

markup
package main

import (
	"encoding/json"
	"fmt"
)

type Book struct {
	Title  string `json:"title"`
	Pages  int    `json:"pages"`
}

func main() {
	b := Book{Title: "Learning Go", Pages: 320}
	data, err := json.Marshal(b)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println(string(data))
}

Unmarshaling JSON into a Struct

json.Unmarshal parses JSON-encoded bytes into a Go value, which must be passed as a pointer so the function can write the decoded data directly into it.

Note: Always pass a pointer to Unmarshal, e.g. &b, so it can actually populate the fields.

Example: Unmarshaling JSON into a Struct

markup
package main

import (
	"encoding/json"
	"fmt"
)

type Book struct {
	Title string `json:"title"`
	Pages int    `json:"pages"`
}

func main() {
	data := []byte(`{"title":"Go in Action","pages":300}`)
	var b Book
	if err := json.Unmarshal(data, &b); err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println(b.Title, b.Pages)
}

Pretty-Printing JSON

json.MarshalIndent works like Marshal but adds a prefix and indentation to each nested level, producing human-readable, formatted JSON instead of one compact line.

Example: Pretty-Printing JSON

markup
package main

import (
	"encoding/json"
	"fmt"
)

type Config struct {
	Host string `json:"host"`
	Port int    `json:"port"`
}

func main() {
	c := Config{Host: "localhost", Port: 8080}
	data, _ := json.MarshalIndent(c, "", "  ")
	fmt.Println(string(data))
}
Common Mistakes
  1. Forgetting struct fields must be exported (capitalized) to be visible to json.Marshal -- unexported fields are silently skipped.
  2. Passing a non-pointer to json.Unmarshal, which fails to actually populate the target since it needs to modify it in place.
  3. Ignoring the error returned by Marshal/Unmarshal, silently proceeding with incomplete or zero-valued data on malformed input.
Chapter Summary
  • json.Marshal converts a Go value into its JSON-encoded byte representation.
  • json.Unmarshal parses JSON bytes into a Go value, which must be passed as a pointer.
  • Only exported struct fields are visible to encoding/json; struct tags control the JSON key names.
  • json.MarshalIndent produces pretty-printed, indented JSON output for readability.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.