Id like to work with JSON in Golang, in particular the elastic search JSON protocol.
The JSON is deeply nested (this is a simple query):
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"and": [
{
"range" : {
"b" : {
"from" : 4,
"to" : "8"
}
},
},
{
"term": {
"a": "john"
}
}
]
}
}
}
}
This structure maps easily to a native data structure in Ruby.
But with Golang, it seems you have to define the exact structure with structs (perhaps generate them programmatically from the JSON source).
Even so, things like arrays of different "types" of objects in JS requires work arounds and custom code. For example the "and" key in the example JSON. (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?
For native golang, use map[string]interface{}
or define a struct. For an other way to access json object easily, may be JsonPath or Jason
If you choose to go the struct route, 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
}
}
}
One of the options is to use gabs library: https://github.com/Jeffail/gabs
It's useful for parsing and generating of the complex json structures.
This is the example of the 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")
Will print:
{"outter":{"inner":{"value":10,"value2":20},"inner2":{"value3":30}}}
Based on this article, https://medium.com/@xcoulon/nested-structs-in-golang-2c750403a007, you should define json tags for each field, then you are able to use nested struct
The example is below, you can paste it to go playground and test it.
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
", config)
}