JSON and Go
25 Jan 2011
Tags: json, technical

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, [[http://json.org][json.org]],
provides a wonderfully clear and concise definition of the standard.

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

* Encoding

To encode JSON data we use the [[https://golang.org/pkg/encoding/json/#Marshal][`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 [[https://golang.org/pkg/encoding/json/#Unmarshal][`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 [[https://golang.org/ref/spec#Struct_types][Go spec]]
  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 [[https://golang.org/pkg/io/#Reader][`io.Reader`]]
and [[https://golang.org/pkg/io/#Writer][`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 [[https://golang.org/pkg/encoding/json/][json package documentation]].
For an example usage of json see the source files of the [[https://golang.org/pkg/net/rpc/jsonrpc/][jsonrpc package]].
