Jon Nicholson
Jon Nicholson

Reputation: 1141

Converting string from HTTP request to data struct in Go

I've got an HTTP Post method, which successfully posts data to an external third party API and returns a response.

I then need data returned from this response to post to my database.

The response contains a few piece of data, but I only need the 'access_token' and 'refresh_token' from it.

As a result, what I'm attempting to do is convert the response from a string into individual components in a new data struct I've created - to then pass to my database.

However, the data is showing as blank, despite it successfully being written to my browser. I'm obviously doing something fundamentally wrong, but not sure what..

Here's my code:

type data struct {
    Access_token  string `json:"access_token"`
    Refresh_token string `json:"refresh_token"`
}

func Fetch(w http.ResponseWriter, r *http.Request) {

    client := &http.Client{}

    q := url.Values{}

    q.Add("grant_type", "authorization_code")
    q.Add("client_id", os.Getenv("ID"))
    q.Add("client_secret", os.Getenv("SECRET"))
    q.Add("redirect_uri", "https://callback-url.com")
    q.Add("query", r.URL.Query().Get("query"))

    req, err := http.NewRequest("POST", "https://auth.truelayer-sandbox.com/connect/token", strings.NewReader(q.Encode()))

    if err != nil {
        log.Print(err)
        fmt.Println("Error was not equal to nil at first stage.")
        os.Exit(1)
    }

    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

    resp, err := client.Do(req)
    if err != nil {
        fmt.Println("Error sending request to server")
        os.Exit(1)
    }

    respBody, _ := ioutil.ReadAll(resp.Body)

    d := data{}

    err = json.NewDecoder(resp.Body).Decode(&d)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(d.Access_token)
    fmt.Println(d.Refresh_token)

    w.WriteHeader(resp.StatusCode)
    w.Write(respBody)

}

Upvotes: 1

Views: 2098

Answers (1)

blackgreen
blackgreen

Reputation: 44935

With ioutil.ReadAll you read the body, already. The second time you pass to NewDecoder(resp.Body) the stream was consumed.

You can use instead json.Unmarshal(respBody, &d).

One more advice, don't ignore the error on ioutil.ReadAll

Upvotes: 6

Related Questions