How can I convert a complex JSON object to a map with all the right types in golang. Do I absolutely have to do the typical Golang thing where I create a struct with the fields that I know will be present or is there a generalized way of getting the fields in all the right types?
Here is an example of a JSON that I want to turn into a map:
{
"people": [
{
"diffs": [
77
],
"original": {
"name": "Nick",
"active": "Active",
"email": "nick@example.com"
},
"id": "21"
}
]
}
You could build a recursive function with a type assertion switch to type assert the JSON array into a multi-dimensional map or a flattened map. Unfortunately, your multi-dimensional map is going to get complicated really quickly.
What I mean is, you often need to map at least a few dimensions (for example: map[string]map[string]map[string]string), when you've got a nested JSON array such as "people" above.
If you tried to flatten a nested JSON array, your keys would end up overlapping (i.e. you can only use the "name" key once). You could tag the keys - something like "name_1" : "Nick", but this solution may not work for your use case.
If you want to go the multi-dimensional route, this package may work well for your needs: http://github.com/Jeffail/gabs
I'll give you a tailored example, and then two examples from the link to gabs's github page:
package main
import (
"fmt"
"github.com/Jeffail/gabs"
)
func main() {
jsonS := `{
"people": [
{
"diffs": [
77
],
"original": {
"name": "Nick",
"active": "Active",
"email": "nick@example.com"
},
"id": "21"
}
]
}`
gabsCon, err := gabs.ParseJSON([]byte(jsonS))
if err != nil {
fmt.Println("gabs ParseJSON failed")
}
n1, ok := gabsCon.Path("people.original.name").Data().(string)
if !ok {
fmt.Println("gabs path failed")
}
fmt.Println(n1)
}
Here's a non-tailored example, which would print - first, second, third):
jsonParsed, _ := gabs.ParseJSON([]byte(`{"array":[ "first", "second", "third" ]}`))
// S is shorthand for Search
children, _ := jsonParsed.S("array").Children()
for _, child := range children {
fmt.Println(child.Data().(string))
}
And, another example, which would print - 1, 2, 3:
jsonParsed, _ := gabs.ParseJSON([]byte(`{"array":[ {"value":1}, {"value":2}, {"value":3} ]}`))
fmt.Println(jsonParsed.Path("array.value").String())