Easily Parse Nested JSON in Go

In this example we will parse and extract JSON from the Instagram API. Specifically, we will retrieve the five latest media from a user.

Grab your Access Token from Instagram and follow along. For the sake of time, we will assume you have an Access Token already.

The Endpoint

The following URL will retrieve the five latest media from a given user. We add the count=5 parameter to limit our results.

https://api.instagram.com/v1/users/self/media/recent/?access_token=ACCESS-TOKEN&count=5

The Response Scheme

Here is the sample response from the Endpoint call.

{pagination: {}, data: [{},{},{}], metadata: {}}

Each object on the data array represent a media object. For our example, we only want the URL of the image, and the permanent link to the post.

data: [
{
...
images: {
thumbnail: {..},
low_resolution: {...},
standard_resolution: {
width: 640,
height: 640,
url: "https://instagram.com/linktotheimage.jpg",
},
},
link: "https://instagram.com/thelink",
},
{...},
{...},
]

Making the call

Now let’s retrieve the JSON response from the endpoint by making a http call in Go.

accessToken := "secure-strings-go-here"count := 5URL := fmt.Sprintf("https://api.instagram.com/v1/users/self/media/recent/?access_token=%s&count=%d", accessToken, count)res, err := http.Get(URL)
if err != nil {
panic(err.Error())
}

Getting the JSON

As you may know, it’s a complex affair to retrieve nested JSON structures with GoLang. We will have to create structs that match each key from our JSON response which can be time consuming if we only want to retrieve two keys.

To simplify our life, we will use, gjson which will allow us to very easily get our data with it’s one-line retrieval and dot notation syntax.

For example, the following line of code will retrieve the image URL from the first object of the data array.

gjson.Get(json, "data.0.images.standard_resolution.url")

For now, let us convert the response to a string so gjson can do its magic.

body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err.Error())
}
bodyString := string(body)

Putting it all together

For convinience, we will make a simple Media struct that contains the link to the instagram post, and the source of image.

type Media struct {
Link, Source string
}

Now, we are ready to extract our information from the json string. We just need a simple for loop to iterate over the data array. We will place our results in a Media array.

out := []Mediafor i := 0; i < count; i++ {
get := fmt.Sprintf("data.%d.link", i)
link := gjson.Get(bodyString, get)
get = fmt.Sprintf("data.%d.images.standard_resolution.url", i)
source := gjson.Get(bodyString, get)
// Appending our results to the media array
media := Media{Link: link.String(), Source: source.String()}
out = append(out, media)
}

Finishing touches

So there we have it, we now have an array of Media which we can easily render on an HTML page or do whatever it is we need to do on it. For convenience, I created a function to simplify this entire process. You can check out the gist here.

import (
"fmt"
"io/ioutil"
"net/http"
"github.com/tidwall/gjson"
)

type Media struct {
Link, Source string
}

// getRecentMedia returns an array of Media objects. Provide an access token and count of how many images to return
func getRecentMedia(accessToken string, count int) []Media {
out := []Media{}
URL := fmt.Sprintf("https://api.instagram.com/v1/users/self/media/recent/?access_token=%s&count=%d", accessToken, count)
res, err := http.Get(URL)
if err != nil {
panic(err.Error())
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err.Error())
}
bodyString := string(body)
for i := 0; i < count; i++ {
get := fmt.Sprintf("data.%d.link", i)
link := gjson.Get(bodyString, get)
get = fmt.Sprintf("data.%d.images.standard_resolution.url", i)
source := gjson.Get(bodyString, get)
media := Media{Link: link.String(), Source: source.String()}
out = append(out, media)

}
return out

}

Jethro Lorenzo Garcia Lising

Written by

Assorted topics. Focused on tech and self-improvement.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade