I'm aware that you can unmarshal arbitrary JSON into a map[string]interface{}
value, and while that works, my JSON response is always defined and consistent, and for simplicity's sake, I'd prefer to unmarshal it as nested structs.
Here's a sample of the JSON response, abbreviated:
{
(...)
"results": [
{
"section": "N.Y. / Region",
"subsection": "",
"title": "Christie Spins His Version of Security Record on Trail",
"abstract": "An examination of Gov. Chris Christie’s record as New Jersey’s top federal prosecutor shows that he has, at times, overstated the significance of the terrorism prosecutions he oversaw.",
"url": "http://www.nytimes.com/2015/12/27/nyregion/Christie-markets-himself-as-protector-to-gain-in-polls.html",
"byline": "By ALEXANDER BURNS and CHARLIE SAVAGE",
"item_type": "Article",
"updated_date": "2015-12-26T18:04:19-5:00",
(...)
"multimedia": [
{
"url": "http://static01.nyt.com/images/2015/12/27/nyregion/27CHRISTIE1/27CHRISTIE1-thumbStandard.jpg",
"format": "Standard Thumbnail",
"height": 75,
"width": 75,
"type": "image",
"subtype": "photo",
"caption": "Gov. Chris Christie of New Jersey spoke about the Sept. 11, 2001, attacks at a Republican conference last month.",
"copyright": "Stephen Crowley/The New York Times"
}
(...)
]
}
]
}
What I've tried
I tried using JSONutils to automate the struct creation and ended up with this (after deleting the fields I didn't want):
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type PoliticsJson struct {
Results []struct {
Multimedia []struct {
URL string `json:"url"`
} `json:"multimedia"`
Title string `json:"title"`
} `json:"results"`
}
func retrieveData() []byte {
url := "http://api.nytimes.com/svc/topstories/v1/politics.json?MYAPIKEY"
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err2 := ioutil.ReadAll(resp.Body)
if err2 != nil {
fmt.Println(err2)
}
return body
}
func main() {
var p PoliticsJson
err := json.Unmarshal(retrieveData(), &p)
if err != nil {
panic(err)
}
fmt.Println(p.Results[0].Title)
}
I basically just want to print out the title and the URL of the last object in the multimedia array. (I'm just trying to get it to work, so please pardon the error handling.)
Here's the error I get: panic: json: cannot unmarshal string into Go value of type []struct { URL string "json:\"url\"" }
The problem is with the Multimedia
struct, apparently. What's confusing me is that this error seems to suggest that it's being interpreted as a string, but I changed the struct to this to make sure:
type PoliticsJson struct {
Results []struct {
Multimedia string `json:"multimedia"`
Title string `json:"title"`
} `json:"results"`
}
And I got panic: json: cannot unmarshal array into Go value of type string
, which suggests it is being interpreted as an array in the JSON.
Again, I basically just want to print out the title and the URL of the last object in the multimedia array.