Decoding with JSON

This lesson provides a detailed explanation on decoding data with JSON by providing coded examples.

Decoding arbitrary data

The json package uses map[string]interface{} and []interface{} values to store arbitrary JSON objects and arrays; it will happily unmarshal any valid JSON blob into a plain interface{} value.

Consider this JSON data, stored in the variable b:

b := []byte(`{"Name": "Wednesday", "Age": 6, "Parents": ["Gomez", "Morticia"]}`)

Without knowing this data’s structure, we can decode it into an interface{} value with Unmarshal:

var f interface{}
err := json.Unmarshal(b, &f)

At this point, the value in f would be a map, whose keys are strings and whose values are themselves stored as empty interface values:

map[string]interface{}{
  "Name": "Wednesday",
  "Age": 6,
  "Parents": []interface{}{
    "Gomez",
    "Morticia",
  },
}

To access this data we can use a type assertion to access f's underlying map[string]interface{}:

m := f.(map[string]interface{})

We can then iterate through the map with a range statement and use a type switch to access its values as their concrete types:

for k, v := range m {
  switch vv := v.(type) {
  case string:
    fmt.Println(k, "is string", vv)
  case int:
    fmt.Println(k, "is int", vv)
  case []interface{}:
    fmt.Println(k, "is an array:")
    for i, u := range vv {
      fmt.Println(i, u)
    }
  default:
    fmt.Println(k, "is of a type I don't know how to handle")
  }
}

In this way, you can work with unknown JSON data while still enjoying the benefits of type safety.

Decoding data into a struct

If we know beforehand the semantics of the json-data, we can then define an appropriate struct and unmarshal into it. For example, in the previous section, we would define:

type FamilyMember struct {
  Name string
  Age int
  Parents []string
}

and then do the unmarshaling with:

var m FamilyMember
err := json.Unmarshal(b, &m)

This allocates a new slice behind the scenes. This is typical of how unmarshal works with the supported reference types (pointers, slices, and maps).

Here is an example that shows how it works:

Get hands-on with 1200+ tech skills courses.