Said  Saifi Said Saifi - 4 months ago 13
JSON Question

How to unmarshal json

I am using http.Get in go to a url which results in the following
{"name":"cassandra","tags":["2.2.6","latest"]} that means it behaves like map[string]string for the name field but in the tags it behaves like map[string][]string so how can I unmarshal this in Go?
I tried using map[string][]string but it did not work

map_image_tags := make(map[string][]string)
res2, err := http.Get(fmt.Sprintf("%s/v2/%s/tags/lists", sconf.RegistryConf.url, Images[i]))
if err != nil {
w.WriteHeader(500)
log.Errorf("could not get tags: %s", err)
return
}
log.Debugf("OK")
js2, err := ioutil.ReadAll(res2.Body)
if err != nil {
w.WriteHeader(500)
log.Errorf("could not read body: %s", err)
return
}
log.Debugf("OK")
err = json.Unmarshal(js2, map_image_tags)
if err != nil {
w.WriteHeader(500)
log.Errorf("could not unmarshal json: %s", err)
return
}


I am getting this log error: could not unmarshal json: invalid character 'p' after top-level value

Answer

If the structure of json data is dynamic you can unmarshal tags into map[string]interface{}:

var encodedTags map[string]interface{}
result := json.Unmarshal([]byte(image_tags), &encodedTags)

Then you can use type assertion to unmarshal the content of tags:

var tags []interface{}
result = json.Unmarshal([]byte(encodedTags["tags"].(string)), &tags)

And here is a full working example on Go Playground.