0

I am new to golang. I was writing a program to parse the json response of the API: https://httpbin.org/get. I have used the following code to parse the response:

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "os"
)

type Headers struct {
    Close  string `json:"Connection"`
    Accept string `json:"Accept"`
}

type apiResponse struct {
    Header Headers `json:"headers"`
    URL    string  `json:"url"`
}

func main() {
    apiRoot := "https://httpbin.org/get"
    req, err := http.NewRequest("GET", apiRoot, nil)
    if err != nil {
        fmt.Println("Couldn't prepare request")
        os.Exit(1)
    }
    response, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    defer response.Body.Close()
    var responseStruct apiResponse
    err = json.NewDecoder(response.Body).Decode(&responseStruct)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    fmt.Printf("%v\n", responseStruct)
}

When I run this code the output is:

$ go run parse.go
{{close } https://httpbin.org/get}

From the output, as we can see the "Accept" key in json response is not decoded. Why is it so? How can I parse that string from response body?

6
  • Headers are not part of the Body. They are already "pre-read" and parsed into http.Repsonse.Header. Commented Oct 9, 2018 at 13:41
  • @mkopriva: It is not headers, the content shown here is from the body of the response. You can test it via postman Commented Oct 9, 2018 at 13:44
  • 2
    @Arun the response is a reflection of the request headers you sent the URL. Your browser sends different headers than the Go http client. Commented Oct 9, 2018 at 13:46
  • @Not_a_Golfer: I have understood the situation. I have set the headers same as the browser, and I got the results. Commented Oct 9, 2018 at 13:52
  • @Arun my bad, I misread your question. Commented Oct 9, 2018 at 18:31

2 Answers 2

1

Your code is doing well but here I think your Accept key does not return from API that's why it's not showing the Accept value. To check the key, value pair of your struct, use the below print method.

fmt.Printf("%+v\n", responseStruct)

To overcome from this situation you need to send Accept with request into header before request the API like:

req.Header.Set("Accept", "value")
response, err := hc.Do(req)
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}

Then you will get the Accept value in decoded struct as :

{Header:{Accept:value Close:close} URL:https://httpbin.org/get}
Sign up to request clarification or add additional context in comments.

3 Comments

Running the code locally, the response doen't contain the Accept value.
@saddam: I have printed that but it does not contain Accept. It shows {Header:{Accept: Close:close} URL:https://httpbin.org/get}
@Arun the response you got from httpbin doesn't contain Accept because you did not send an Accept header. Send one and you'll get one back.
0

apiResponse is unexported - you need to change it to something like APIResponse. You may find that pasting the JSON you want to decode into https://mholt.github.io/json-to-go/ will make all the code you need!

type AutoGenerated struct {
    Args struct {
    } `json:"args"`
    Headers struct {
        Accept                  string `json:"Accept"`
        AcceptEncoding          string `json:"Accept-Encoding"`
        AcceptLanguage          string `json:"Accept-Language"`
        Connection              string `json:"Connection"`
        Dnt                     string `json:"Dnt"`
        Host                    string `json:"Host"`
        UpgradeInsecureRequests string `json:"Upgrade-Insecure-Requests"`
        UserAgent               string `json:"User-Agent"`
    } `json:"headers"`
    Origin string `json:"origin"`
    URL    string `json:"url"`
}

2 Comments

I think the apiResponse unexported is not a problem because I am calling it from the same file. Thanks for providing link to json-to-go tool.
Correct - it is the members that need to be exported for the JSON package to pick them up. play.golang.org/p/P2QRiaE6Gfg shows your code works fine as long as the API returns the headers you expect.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.