# JSON and Go
25 Jan 2011
Tags: json, technical
Summary: How to generate and consume JSON-formatted data in Go.
OldURL: /json-and-go

Andrew Gerrand

## Introduction

JSON (JavaScript Object Notation) is a simple data interchange format.
Syntactically it resembles the objects and lists of JavaScript.
It is most commonly used for communication between web back-ends and JavaScript
programs running in the browser,
but it is used in many other places, too.
Its home page, [json.org](http://json.org),
provides a wonderfully clear and concise definition of the standard.

With the [json package](https://golang.org/pkg/encoding/json/) it's a
snap to read and write JSON data from your Go programs.

## Encoding

To encode JSON data we use the [`Marshal`](https://golang.org/pkg/encoding/json/#Marshal) function.

	func Marshal(v interface{}) ([]byte, error)

Given the Go data structure, `Message`,

	type Message struct {
	    Name string
	    Body string
	    Time int64
	}

and an instance of `Message`

	m := Message{"Alice", "Hello", 1294706395881547000}

we can marshal a JSON-encoded version of m using `json.Marshal`:

	b, err := json.Marshal(m)

If all is well, `err` will be `nil` and `b` will be a `[]byte` containing this JSON data:

	b == []byte(`{"Name":"Alice","Body":"Hello","Time":1294706395881547000}`)

Only data structures that can be represented as valid JSON will be encoded:

  - JSON objects only support strings as keys;
    to encode a Go map type it must be of the form `map[string]T` (where `T`
    is any Go type supported by the json package).

  - Channel, complex, and function types cannot be encoded.

  - Cyclic data structures are not supported; they will cause `Marshal` to go into an infinite loop.

  - Pointers will be encoded as the values they point to (or 'null' if the pointer is `nil`).

The json package only accesses the exported fields of struct types (those
that begin with an uppercase letter).
Therefore only the the exported fields of a struct will be present in the JSON output.

## Decoding

To decode JSON data we use the [`Unmarshal`](https://golang.org/pkg/encoding/json/#Unmarshal) function.

	func Unmarshal(data []byte, v interface{}) error

We must first create a place where the decoded data will be stored

	var m Message

and call `json.Unmarshal`, passing it a `[]byte` of JSON data and a pointer to `m`

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

If `b` contains valid JSON that fits in `m`,
after the call `err` will be `nil` and the data from `b` will have been
stored in the struct `m`,
as if by an assignment like:

	m = Message{
	    Name: "Alice",
	    Body: "Hello",
	    Time: 1294706395881547000,
	}

How does `Unmarshal` identify the fields in which to store the decoded data?
For a given JSON key `"Foo"`,
`Unmarshal` will look through the destination struct's fields to find (in
order of preference):

  - An exported field with a tag of `"Foo"` (see the [Go spec](https://golang.org/ref/spec#Struct_types)
    for more on struct tags),

  - An exported field named `"Foo"`, or

  - An exported field named `"FOO"` or `"FoO"` or some other case-insensitive match of `"Foo"`.

What happens when the structure of the JSON data doesn't exactly match the Go type?

	b := []byte(`{"Name":"Bob","Food":"Pickle"}`)
	var m Message
	err := json.Unmarshal(b, &m)

`Unmarshal` will decode only the fields that it can find in the destination type.
In this case, only the Name field of m will be populated,
and the Food field will be ignored.
This behavior is particularly useful when you wish to pick only a few specific
fields out of a large JSON blob.
It also means that any unexported fields in the destination struct will
be unaffected by `Unmarshal`.

But what if you don't know the structure of your JSON data beforehand?

## Generic JSON with interface{}

The `interface{}` (empty interface) type describes an interface with zero methods.
Every Go type implements at least zero methods and therefore satisfies the empty interface.

The empty interface serves as a general container type:

	var i interface{}
	i = "a string"
	i = 2011
	i = 2.777

A type assertion accesses the underlying concrete type:

	r := i.(float64)
	fmt.Println("the circle's area", math.Pi*r*r)

Or, if the underlying type is unknown, a type switch determines the type:

	switch v := i.(type) {
	case int:
	    fmt.Println("twice i is", v*2)
	case float64:
	    fmt.Println("the reciprocal of i is", 1/v)
	case string:
	    h := len(v) / 2
	    fmt.Println("i swapped by halves is", v[h:]+v[:h])
	default:
	    // i isn't one of the types above
	}

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.  The default concrete Go types are:

  - `bool` for JSON booleans,

  - `float64` for JSON numbers,

  - `string` for JSON strings, and

  - `nil` for JSON null.

## Decoding arbitrary data

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 Go value in `f` would be a map whose keys are strings
and whose values are themselves stored as empty interface values:

	f = 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 float64:
	        fmt.Println(k, "is float64", 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.

## Reference Types

Let's define a Go type to contain the data from the previous example:

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

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

Unmarshaling that data into a `FamilyMember` value works as expected,
but if we look closely we can see a remarkable thing has happened.
With the var statement we allocated a `FamilyMember` struct,
and then provided a pointer to that value to `Unmarshal`,
but at that time the `Parents` field was a `nil` slice value.
To populate the `Parents` field, `Unmarshal` allocated a new slice behind the scenes.
This is typical of how `Unmarshal` works with the supported reference types
(pointers, slices, and maps).

Consider unmarshaling into this data structure:

	type Foo struct {
	    Bar *Bar
	}

If there were a `Bar` field in the JSON object,
`Unmarshal` would allocate a new `Bar` and populate it.
If not, `Bar` would be left as a `nil` pointer.

From this a useful pattern arises: if you have an application that receives
a few distinct message types,
you might define "receiver" structure like

	type IncomingMessage struct {
	    Cmd *Command
	    Msg *Message
	}

and the sending party can populate the `Cmd` field and/or the `Msg` field
of the top-level JSON object,
depending on the type of message they want to communicate.
`Unmarshal`, when decoding the JSON into an `IncomingMessage` struct,
will only allocate the data structures present in the JSON data.
To know which messages to process, the programmer need simply test that
either `Cmd` or `Msg` is not `nil`.

## Streaming Encoders and Decoders

The json package provides `Decoder` and `Encoder` types to support the common
operation of reading and writing streams of JSON data.
The `NewDecoder` and `NewEncoder` functions wrap the [`io.Reader`](https://golang.org/pkg/io/#Reader)
and [`io.Writer`](https://golang.org/pkg/io/#Writer) interface types.

	func NewDecoder(r io.Reader) *Decoder
	func NewEncoder(w io.Writer) *Encoder

Here's an example program that reads a series of JSON objects from standard input,
removes all but the `Name` field from each object,
and then writes the objects to standard output:

	package main

	import (
	    "encoding/json"
	    "log"
	    "os"
	)

	func main() {
	    dec := json.NewDecoder(os.Stdin)
	    enc := json.NewEncoder(os.Stdout)
	    for {
	        var v map[string]interface{}
	        if err := dec.Decode(&v); err != nil {
	            log.Println(err)
	            return
	        }
	        for k := range v {
	            if k != "Name" {
	                delete(v, k)
	            }
	        }
	        if err := enc.Encode(&v); err != nil {
	            log.Println(err)
	        }
	    }
	}

Due to the ubiquity of Readers and Writers,
these `Encoder` and `Decoder` types can be used in a broad range of scenarios,
such as reading and writing to HTTP connections,
WebSockets, or files.

## References

For more information see the [json package documentation](https://golang.org/pkg/encoding/json/).
For an example usage of json see the source files of the [jsonrpc package](https://golang.org/pkg/net/rpc/jsonrpc/).
