Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to work with nested JSON structures in Golang?

Tags:

json

go

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?

like image 555
zino Avatar asked Aug 03 '15 22:08

zino


People also ask

What does JSON Unmarshal do?

To unmarshal a JSON array into a slice, Unmarshal resets the slice length to zero and then appends each element to the slice. As a special case, to unmarshal an empty JSON array into a slice, Unmarshal replaces the slice with a new empty slice.

What is marshal and Unmarshal in Golang?

Marshal and Unmarshal convert a string into JSON and vice versa. Encoding and decoding convert a stream into JSON and vice versa.

Can you nest objects in JSON?

Objects can be nested inside other objects. Each nested object must have a unique access path. The same field name can occur in nested objects in the same document.


2 Answers

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
        }
    }
}

Source: http://talks.golang.org/2012/10things.slide#4

like image 151
Brownbay Avatar answered Dec 29 '22 01:12

Brownbay


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}}}
like image 37
Mik Avatar answered Dec 29 '22 01:12

Mik