I ran jsonutils
on what the New York Times top stories API, and it spit out what looked like the correct format. But I'm getting panic: json: cannot unmarshal string into Go value of type []string
when I run my code. Is this user error?
For reference, here's a sample API response:
{
"status": "OK",
"copyright": "Copyright (c) 2015 The New York Times Company. All Rights Reserved.",
"section": "politics",
"last_updated": "2015-12-27T14:40:04-05:00",
"num_results": 26,
"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",
"created_date": "2015-12-26T12:13:30-5:00",
"published_date": "2015-12-27T00:00:00-5:00",
"material_type_facet": "News",
"kicker": "",
"des_facet": [
"Presidential Election of 2016",
"Terrorism"
],
"org_facet": [
"Republican Party"
],
"per_facet": [
"Christie, Christopher J"
],
"geo_facet": [
"New Jersey"
],
"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"
},
{
"url": "http://static01.nyt.com/images/2015/12/27/nyregion/27CHRISTIE1/27CHRISTIE1-thumbLarge.jpg",
"format": "thumbLarge",
"height": 150,
"width": 150,
"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"
},
{
"url": "http://static01.nyt.com/images/2015/12/27/nyregion/27CHRISTIE1/27CHRISTIE1-articleInline.jpg",
"format": "Normal",
"height": 126,
"width": 190,
"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"
},
{
"url": "http://static01.nyt.com/images/2015/12/27/nyregion/27CHRISTIE1/27CHRISTIE1-mediumThreeByTwo210.jpg",
"format": "mediumThreeByTwo210",
"height": 140,
"width": 210,
"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"
},
{
"url": "http://static01.nyt.com/images/2015/12/27/nyregion/27CHRISTIE1/27CHRISTIE1-superJumbo.jpg",
"format": "superJumbo",
"height": 1363,
"width": 2048,
"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"
}
]
}
]
Accordingly, jsonutils
gave this structure:
type PoliticsJson struct {
Copyright string `json:"copyright"`
LastUpdated time.Time `json:"last_updated"`
NumResults int64 `json:"num_results"`
Results []struct {
Abstract string `json:"abstract"`
Byline string `json:"byline"`
CreatedDate string `json:"created_date"`
DesFacet []string `json:"des_facet"`
GeoFacet []string `json:"geo_facet"`
ItemType string `json:"item_type"`
Kicker string `json:"kicker"`
MaterialTypeFacet string `json:"material_type_facet"`
Multimedia []struct {
Caption string `json:"caption"`
Copyright string `json:"copyright"`
Format string `json:"format"`
Height int64 `json:"height"`
Subtype string `json:"subtype"`
Type string `json:"type"`
URL string `json:"url"`
Width int64 `json:"width"`
} `json:"multimedia"`
OrgFacet []string `json:"org_facet"`
PerFacet []string `json:"per_facet"`
PublishedDate string `json:"published_date"`
Section string `json:"section"`
Subsection string `json:"subsection"`
Title string `json:"title"`
UpdatedDate string `json:"updated_date"`
URL string `json:"url"`
} `json:"results"`
Section string `json:"section"`
Status string `json:"status"`
}
That looks right.
My go code is pretty simple:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type PoliticsJson struct {
Copyright string `json:"copyright"`
LastUpdated time.Time `json:"last_updated"`
NumResults int64 `json:"num_results"`
Results []struct {
Abstract string `json:"abstract"`
Byline string `json:"byline"`
CreatedDate string `json:"created_date"`
DesFacet []string `json:"des_facet"`
GeoFacet []string `json:"geo_facet"`
ItemType string `json:"item_type"`
Kicker string `json:"kicker"`
MaterialTypeFacet string `json:"material_type_facet"`
Multimedia []struct {
Caption string `json:"caption"`
Copyright string `json:"copyright"`
Format string `json:"format"`
Height int64 `json:"height"`
Subtype string `json:"subtype"`
Type string `json:"type"`
URL string `json:"url"`
Width int64 `json:"width"`
} `json:"multimedia"`
OrgFacet []string `json:"org_facet"`
PerFacet []string `json:"per_facet"`
PublishedDate string `json:"published_date"`
Section string `json:"section"`
Subsection string `json:"subsection"`
Title string `json:"title"`
UpdatedDate string `json:"updated_date"`
URL string `json:"url"`
} `json:"results"`
Section string `json:"section"`
Status string `json:"status"`
}
func retrieveData() []byte {
url := "http://api.nytimes.com/svc/topstories/v1/politics.json?api-key=MYAPIKEY"
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
return body
}
func main() {
var p PoliticsJson
err := json.Unmarshal(retrieveData(), &p)
if err != nil {
panic(err)
}
fmt.Println(p)
}
Edit
It seems to be the []string
s this is having trouble with. Removing all of them but Multimedia
, I get
panic: json: cannot unmarshal string into Go value of type []struct { Caption string "json:\"caption\""; Copyright string "json:\"copyright\""; Format string "json:\"format\""; Height int64 "json:\"height\""; Subtype string "json:\"subtype\""; Type string "json:\"type\""; URL string "json:\"url\""; Width int64 "json:\"width\"" }
It apparently doesn't like unmarshaling the mutlimedia
key into an array of multimedia
structs for some reason…?
Removing all of the fields for multimedia
except URL
gives this:
panic: json: cannot unmarshal string into Go value of type []struct { URL string "json:\"url\"" }
And removing the multimedia
struct slice entirely gives the expected parsed JSON result. So it seems like it's treating the multimedia
JSON array as a string…?
But changing it to
Multimedia string `json:"multimedia"`
Gives the error panic: json: cannot unmarshal array into Go value of type string
, which suggests it _is_treating it as an array.