Reputation: 9875
Writing my first Go Application I am learning to make a basic api call and parse the json response. I am pretty sure I am not casting my types correctly and my response is
false
0
0
0
0 false
0
If I create a few arrays with data in them I can get that response but when I add this more complexed json response to the mix things get more confusing which leads me to be quite positive I am not casting correctly.
This is my current code after playing around and changing things in order to break stuff and try and figure things out.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type Payload struct {
results Data
}
type Data struct {
poster_path string
adult bool
overview string
release_date string
genre_ids int
id int
original_title string
original_language string
title string
backdrop_path string
popularity float64
vote_count int
video bool
vote_average float64
}
type poster_path map[string]string
type adult map[string]bool
type overview map[string]string
type release_date map[string]string
type genre_ids map[string]int
type id map[string]int
type original_title map[string]string
type original_language map[string]string
type title map[string]string
type backdrop_path map[string]string
type popularity map[string]float64
type vote_count map[string]int
type video map[string]bool
type vote_average map[string]float64
func main() {
// http://image.tmdb.org/t/p/w185
url := "https://api.themoviedb.org/3/movie/top_rated?api_key=####APIKEYHERE######"
res, err := http.Get(url)
if err != nil {
panic(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
var p Payload
err = json.Unmarshal(body, &p)
if err != nil {
panic(err)
}
fmt.Println(
p.results.poster_path, "\n", p.results.adult,
p.results.overview, "\n", p.results.release_date,
p.results.genre_ids, "\n", p.results.id,
p.results.original_title, "\n", p.results.original_language,
p.results.title, "\n", p.results.backdrop_path,
p.results.popularity, "\n", p.results.vote_count,
p.results.video, "\n", p.results.vote_average,
)
}
This is what the JSON response looks like,
{
"page": 1,
"results": [
{
"poster_path": "/lIv1QinFqz4dlp5U4lQ6HaiskOZ.jpg",
"adult": false,
"overview": "Under the direction of a ruthless instructor, a talented young drummer begins to pursue perfection at any cost, even his humanity.",
"release_date": "2014-10-10",
"genre_ids": [
18,
10402
],
"id": 244786,
"original_title": "Whiplash",
"original_language": "en",
"title": "Whiplash",
"backdrop_path": "/6bbZ6XyvgfjhQwbplnUh1LSj1ky.jpg",
"popularity": 9.685051,
"vote_count": 1706,
"video": false,
"vote_average": 8.36
}
}
A few things that stand out to me,
When I tried to cast the float I was confused about casting from float32
to float64
There is an array inside the json response which was confusing when trying to cast,
"genre_ids": [
36,
18,
53,
10752
],
Upvotes: 1
Views: 1838
Reputation: 8390
First of all, you are missing a closing square bracket ]
at the end of results
in your JSON.
Secondly, you did not structure your structs according to the JSON you receive.
Lastly, use JSON tags after each exported field in your struct when dealing with Unmarshal/marshaling to help Go detect the appropriate fields (not necessary if you name the fields according to how Unmarshal/marshal identify fields.
type Payload struct {
Page int
Results []Data
}
type Data struct {
PosterPath string `json:"poster_path"`
Adult bool `json:"adult"`
Overview string `json:"overview"`
ReleaseDate string `json:"release_date"`
GenreIds []int `json:"genre_ids"`
Id int `json:"id"`
OriginalTitle string `json:"original_title"`
OriginalLanguage string `json:"original_language"`
Title string `json:"title"`
BackdropPath string `json:"backdrop_path"`
Popularity float64 `json:"popularity"`
VoteCount int `json:"vote_count"`
Video bool `json:"video"`
VoteAverage float64 `json:"vote_average"`
}
Note that GenreIds
has to be []int
to match the JSON data as well. And it's a good idea not to use CamelCase in Go.
See https://play.golang.org/p/VduPD9AY84
Upvotes: 1
Reputation: 77955
Is a common beginners mistake. Due to language design, the encoding/json
package can only unmarshal into exported fields.
From the encoding/json
package:
To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. Unmarshal will only set exported fields of the struct.
To export a field, simply use a capital first letter of the name. Eg.:
type Payload struct {
Results Data
}
instead of
type Payload struct {
results Data
}
Upvotes: 4