JSON in Go
Working with JSON isn't always straightforward
Luckily Go and JSON get along famously
Decoding
type GameOfThrones struct {
Awesome bool
Seasons int
Hodor string
}
raw := `{"awesome": true, "seasons": 5, "hodor": "Hodor"}`
got := &GameOfThrones{}
err := json.Unmarshal([]byte(raw), &got)
if err != nil {
panic(err) // Or something more useful
}
fmt.Println(got)
// &{true 5 Hodor}
fmt.Println(got.Hodor)
// Hodor
Encoding
type GameOfThrones struct {
Awesome bool
Seasons int
Hodor string
}
got := &GameOfThrones{
Awesome: true,
Seasons: 5,
Hodor: "Hodor"}
gotJson, err := json.Marshal(got)
if err != nil {
panic(err)
}
fmt.Println(string(gotJson))
// {"Awesome":true,"Seasons":5,"Hodor":"Hodor"}
But note that the fields are capitalized
What if we don't want capitals?
Tags
type GameOfThrones struct {
Awesome bool `json:"awesome_sauce"`
Seasons int `json:"number-of-seasons"`
Hodor string `json:"Hodor?"`
}
got := &GameOfThrones{
Awesome: true,
Seasons: 5,
Hodor: "Hodor"}
g, _ := json.Marshal(got)
fmt.Println(string(g))
// {"awesome_sauce":true,"number-of-seasons":5,"Hodor?":"Hodor"}
What about nested fields?
Nested JSON
type User struct {
Name string `json:"name"`
Email string `json:"email"`
Twitter Twitter `json:"twitter"`
}
type Twitter struct {
Id int `json:"id"`
Username string `json:"username"`
}
raw := `{
"name":"Hodor",
"email":"hodor@hodor.io",
"twitter": {"id": 123,"username": "hodor"}
}`
user := &User{}
json.Unmarshal([]byte(raw), &user)
fmt.Println(user.Email)
// hodor@hodor.io
fmt.Println(user.Twitter.Id)
// 123
Default Values
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Interests []string `json:"interests"`
Twitter Twitter `json:"twitter"`
}
type Twitter struct {
Id int `json:"id"`
Username string `json:"username"`
}
user := &User{}
u, _ := json.Marshal(user)
fmt.Println(string(u))
// {"name":"","age":0,"interests":null,"twitter":{"id":0,"username":""}}
Null Values
type User struct {
Name *string `json:"name"`
Age *int `json:"age"`
Interests []string `json:"interests"`
Twitter *Twitter `json:"twitter"`
}
type Twitter struct {
Id int `json:"id"`
Username string `json:"username"`
}
user := &User{}
u, _ := json.Marshal(user)
fmt.Println(string(u))
// {"name":null,"age":null,"interests":null,"twitter":null}
Omitting Fields
type Country struct {
Name string `json:"name"`
NationalDance string `json:"national_dance,omitempty"`
NationalDrink string `json:"-"`
nuclearLaunchCode int
}
russia := &Country{"Russia", "troika", "vodka", 4321}
r, _ := json.Marshal(russia)
fmt.Println(string(r))
// {"name":"Russia","national_dance":"troika"}
usa := &Country{"USA", "", "bourbon", 1234}
u, _ := json.Marshal(usa)
fmt.Println(string(u))
//{"name":"USA"}
YOLO Decoding
AKA structs are for suckas*
*not actually true
Decoding into a map
raw := `{"pi":3.14,"langs":["go","c","haskell","erlang","python"]}`
var yolo map[string]interface{}
if err := json.Unmarshal([]byte(raw), &yolo);
err != nil {
panic(err)
}
pi := yolo["pi"].(float64)
fmt.Println(pi)
// 3.14
langs := yolo["langs"].([]interface{})
fmt.Println(len(langs))
// 5
lang1 := langs[0].(string)
fmt.Println(lang1)
// go
Thanks!
JSON in Go
By zeroviscosity
JSON in Go
Presented at the Toronto Go Meetup 2015-03-12
- 2,108