wuno
wuno

Reputation: 9875

Api Request With Go Parse Json Response

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

Answers (2)

Pandemonium
Pandemonium

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

ANisus
ANisus

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

Related Questions