What's the best way to work with nested JSON structures in Golang?
I would like to work with JSON in Golang, in particular the JSON protocol with elastic search.
JSON is deeply nested (this is a simple request):
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"and": [
{
"range" : {
"b" : {
"from" : 4,
"to" : "8"
}
},
},
{
"term": {
"a": "john"
}
}
]
}
}
}
}
This structure easily maps to Ruby's own data structure.
But with Golang, it seems like you have to define the exact structure with the structures (maybe generate them programmatically from a JSON source).
However, things like arrays of different "types" of objects in JS require workarounds and custom code. For example, "and" is the key in the JSON example. ( http://mattyjwilliams.blogspot.co.uk/2013/01/using-go-to-unmarshal-json-lists-with.html ).
Is there a better way to work with JSON in Golang?
source to share
If you decide to go the structure path, consider this example:
{"data": {"children": [
{"data": {
"title": "The Go homepage",
"url": "http://golang.org/"
}},
...
]}}
// -----------
type Item struct {
Title string
URL string
}
type Response struct {
Data struct {
Children []struct {
Data Item
}
}
}
source to share
One option is to use the gabs library: https://github.com/Jeffail/gabs
This is useful for parsing and generating complex json structures.
This is an example of nested json generation from the README:
jsonObj := gabs.New()
// or gabs.Consume(jsonObject) to work on an existing map[string]interface{}
jsonObj.Set(10, "outter", "inner", "value")
jsonObj.SetP(20, "outter.inner.value2")
jsonObj.Set(30, "outter", "inner2", "value3")
This will print:
{"outter":{"inner":{"value":10,"value2":20},"inner2":{"value3":30}}}
source to share
Based on this article, https://medium.com/@xcoulon/nested-structs-in-golang-2c750403a007 , you have to define json tags for each field, then you can use nested structure
Example below, you can insert it into playground pad and check it out.
package main
import (
"encoding/json"
"fmt"
)
type Config struct {
Server struct {
Host string 'json:"host"'
Port string 'json:"port"'
} 'json:"server"'
Postgres struct {
Host string 'json:"host"'
User string 'json:"user"'
Password string 'json:"password"'
DB string 'json:"db"'
} 'json:"database"'
}
func main() {
jsonConfig := []byte('{
"server":{
"host":"localhost",
"port":"8080"},
"database":{
"host":"localhost",
"user":"db_user",
"password":"supersecret",
"db":"my_db"}}')
var config Config
err := json.Unmarshal(jsonConfig, &config)
if err != nil {
panic(err)
}
fmt.Printf("Config: %+v\n", config)
}
source to share