Golang encoding/json

From wikinotes

Conveniently, the builtin types are ready for json serialization/deserialization without any additional work.

Deserializing

Builtins

// string, int
var name string
json.Unmarshal([]byte(`"vaderd"`), &name)
fmt.Println(name)

// array, slice
var items [2]string
json.Unmarshal([]byte(`["abc", "def"]`), &items)
fmt.Println(items)  // [abc def]

Arbitrary JSON

You can parse arbitrary json objects using interface{}.

projects_json := []byte(`{"Projects": [{"Name": "a"}, {"Name": "b"}]}`)
var projects interface{}
json.Unmarshal(projects_json, &projects)

projects_casted := projects.(map[string]interface{})  // type-assertion -- if type does not match, panics
fmt.Println(projects_casted["Projects"])              // [map[Name:a] map[Name:b]]

Json-Object to Struct

type User struct {
    id   int
    Name string
}

var user User
data := []byte(`{"id": 123, "Name": "vaderd"}`)
json.Unmarshal(data, &user)
fmt.Println(user.Name)

Unlike the serialization behaviour, even un-exported fields will be set on the object.
You assume the JSON object knows what it wants set.

type User struct {
    id   int
    Name string
}

func (u *User) Id() int {
    return u.id
}

var user2 User
data := []byte(`{"id": 123, "Name": "vaderd"}`)
json.Unmarshal(data, &user2)
fmt.Println(user.Id())  // 123

Serializing

Builtins

// string, int
bytes, _ := json.Marshal("vaderd")
fmt.Println(string(bytes))  // '"vaderd"'

// array, slice
names := []string{"maize", "sprout"}
bytes, _ := json.Marshal(names)
fmt.Println(string(bytes))  // '["maize", "sprout"]'

Struct to Json-Object

Only exported fields will be serialized by default.

type User struct {
    id   int
    Name string
}

user := User{id: 1, Name: "will"}
bytes, _ := json.Marshal(user)
fmt.Println(string(bytes))  // '{"Name": "will"}'