Attempting to Learn Go - Continuing REST Adventures

Continuing Adventures

Last time we put together a small program to query a REST API and print out the response. Not overly useful but a good learning experience none the less. This time we’re going to take that and actually try to do something with it - hopefully, I’ll figure out what before we get to the end of the post.

The JSON Response

In order to use the JSON response from httpbin.org and we’ll need to get it from JSON into a structure Go can work with. Using our example response from the previous post we can take a shortcut to create our struct over at JSON-to-Go site

Here’s our original object…

{
  "args": {},
  "headers": {
    "Accept-Encoding": "gzip",
    "Connection": "close",
    "Host": "httpbin.org",
    "User-Agent": "Go-http-client/1.1"
  },
  "origin": "68.211.xx.xx",
  "url": "https://httpbin.org/get"
}

And our auto-generated result…

type AutoGenerated struct {
  Args struct {
  } `json:"args"`
  Headers struct {
    AcceptEncoding string `json:"Accept-Encoding"`
    Connection     string `json:"Connection"`
    Host           string `json:"Host"`
    UserAgent      string `json:"User-Agent"`
  } `json:"headers"`
  Origin string `json:"origin"`
  URL    string `json:"url"`
}

That’s a pretty good translation but, we don’t want exactly what the site spat out at us. We’re going to change the Args and the Header sections a bit making them a map.

type HTTPBinResponse struct {
  Args    map[string]string `json:"args"`
  Headers map[string]string `json:"headers"`
  Origin  string            `json:"origin"`
  URL     string            `json:"url"`
}

A map is basically a key/value pair, which is perfect for holding query parameters and headers. This makes our struct a bit simpler to use and we can just loop through Args, or Headers if need be.

We have only made a few other small changes from the last post so I won’t go back through the entire thing again. First, we’ve updated the URL we are calling to include two query parameters. This is so we can use our new Args map.

  APIURL := "https://httpbin.org/get?arg1=one&arg2=two"

Jumping down to after our response is received we create a new variable r of type HTTPBinResponse. This holds the struct we created for our response. Next, we use json.Unmarshal to “un-marshal” the JSON object into our struct.

  var r HTTPBinResponse
  json.Unmarshal(body, &r)

Now all’s that if left is - that’s right printing the data. We’ll print it out a couple different ways, first, the full struct and the User Agent returned and finally the second argument. In practice you may not know exactly which headers (other than the standard HTTP headers) or arguments are returned but since this is just an example we just go for it.

  fmt.Printf("%#v\n\n", r)
  fmt.Printf("%v\n\n", r.Headers["User-Agent"])
  fmt.Printf("%v\n", r.Args["arg2"])

You can find the code for this and most of the other Attempting to Learn Go posts in the repo on GitHub.

{% github shindakun/atlg %}


Enjoy this post?
How about buying me a coffee?