DEV Community

Cover image for Parse JSON API response in Go
billylkc
billylkc

Posted on Edited on

Parse JSON API response in Go

(You can find my original post here - data-gulu.com)


Introduction

When you are hosting your model result as a micro-services, or scrapping data from websites, you will often find yourself working on some Restful API JSON object. In this post, I will show you how easily we can work with JSON data in Go.

Overview

  1. Get JSON response from sample API hosting site - reqres
  2. Generate go struct from the response - json-to-go
  3. Unmarshal JSON response to go struct
  4. Loop through the struct and print data from the result

Get Requests



package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    resp, err := http.Get("https://reqres.in/api/users?page=2")
    if err != nil {
        fmt.Println("No response from request")
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body) // response body is []byte
    fmt.Println(string(body))              // convert to string before print
}


Enter fullscreen mode Exit fullscreen mode

Result JSON



{"page":2,"per_page":6,"total":12,"total_pages":2,"data":[{"id":7,"email":"michael.lawson@reqres.in","first_name":"Michael","last_name":"Lawson","avatar":"https://reqres.in/img/faces/7-image.jpg"},{"id":8,"email":"lindsay.ferguson@reqres.in","first_name":"Lindsay","last_name":"Ferguson","avatar":"https://reqres.in/img/faces/8-image.jpg"},{"id":9,"email":"tobias.funke@reqres.in","first_name":"Tobias","last_name":"Funke","avatar":"https://reqres.in/img/faces/9-image.jpg"},{"id":10,"email":"byron.fields@reqres.in","first_name":"Byron","last_name":"Fields","avatar":"https://reqres.in/img/faces/10-image.jpg"},{"id":11,"email":"george.edwards@reqres.in","first_name":"George","last_name":"Edwards","avatar":"https://reqres.in/img/faces/11-image.jpg"},{"id":12,"email":"rachel.howell@reqres.in","first_name":"Rachel","last_name":"Howell","avatar":"https://reqres.in/img/faces/12-image.jpg"}],"support":{"url":"https://reqres.in/#support-heading","text":"To keep ReqRes free, contributions towards server costs are appreciated!"}}


Enter fullscreen mode Exit fullscreen mode

Convert JSON response

You can go to this site - JSON to go to convert JSON response to Go struct very easily.

Parse JSON to go struct

Unmarshal JSON to Go struct

You can then unmarshal the []byte from the GET response to the Response struct that we just auto-generated



// Generated go struct
type Response struct {
    Page       int `json:"page"`
    PerPage    int `json:"per_page"`
    Total      int `json:"total"`
    TotalPages int `json:"total_pages"`
    Data       []struct {
        ID        int    `json:"id"`
        Email     string `json:"email"`
        FirstName string `json:"first_name"`
        LastName  string `json:"last_name"`
        Avatar    string `json:"avatar"`
    } `json:"data"`
    Support struct {
        URL  string `json:"url"`
        Text string `json:"text"`
    } `json:"support"`
}

// snippet only
var result Response
if err := json.Unmarshal(body, &result); err != nil {   // Parse []byte to go struct pointer
    fmt.Println("Can not unmarshal JSON")
}
fmt.Println(PrettyPrint(result))


Enter fullscreen mode Exit fullscreen mode

Response struct preview (partial)



{
    "page": 2,
    "per_page": 6,
    "total": 12,
    "total_pages": 2,
    "data": [
    {
        "id": 7,
        "email": "michael.lawson@reqres.in",
        "first_name": "Michael",
        "last_name": "Lawson",
        "avatar": "https://reqres.in/img/faces/7-image.jpg"
    },
        {
        "id": 8,
        "email": "lindsay.ferguson@reqres.in",
        "first_name": "Lindsay",
        "last_name": "Ferguson",
        "avatar": "https://reqres.in/img/faces/8-image.jpg"
    }
    ]
}


Enter fullscreen mode Exit fullscreen mode

Finally loop through the data node and print out the FirstName of the result



// Loop through the data node for the FirstName
for _, rec := range result.Data {
fmt.Println(rec.FirstName)
}

Enter fullscreen mode Exit fullscreen mode




Complete code




package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)

type Response struct {
Page int json:"page"
PerPage int json:"per_page"
Total int json:"total"
TotalPages int json:"total_pages"
Data []struct {
ID int json:"id"
Email string json:"email"
FirstName string json:"first_name"
LastName string json:"last_name"
Avatar string json:"avatar"
} json:"data"
Support struct {
URL string json:"url"
Text string json:"text"
} json:"support"
}

func main() {

<span class="c">// Get request</span>
<span class="n">resp</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">http</span><span class="o">.</span><span class="n">Get</span><span class="p">(</span><span class="s">"https://reqres.in/api/users?page=2"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"No response from request"</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="n">resp</span><span class="o">.</span><span class="n">Body</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span>
<span class="n">body</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">ioutil</span><span class="o">.</span><span class="n">ReadAll</span><span class="p">(</span><span class="n">resp</span><span class="o">.</span><span class="n">Body</span><span class="p">)</span> <span class="c">// response body is []byte</span>

<span class="k">var</span> <span class="n">result</span> <span class="n">Response</span>
<span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">json</span><span class="o">.</span><span class="n">Unmarshal</span><span class="p">(</span><span class="n">body</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">result</span><span class="p">);</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>  <span class="c">// Parse []byte to the go struct pointer</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Can not unmarshal JSON"</span><span class="p">)</span>
<span class="p">}</span>

<span class="c">// fmt.Println(PrettyPrint(result))</span>

<span class="c">// Loop through the data node for the FirstName</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">rec</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">result</span><span class="o">.</span><span class="n">Data</span> <span class="p">{</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">rec</span><span class="o">.</span><span class="n">FirstName</span><span class="p">)</span>
<span class="p">}</span>
Enter fullscreen mode Exit fullscreen mode

}

// PrettyPrint to print struct in a readable way
func PrettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", "\t")
return string(s)
}

Enter fullscreen mode Exit fullscreen mode




Demo

Parson JSON with Go

(You can find my original post here - data-gulu.com)

Top comments (3)

Collapse
 
maseo9 profile image
MasEo9 •

This was incredibly helpful, thanks so much for the post.

Collapse
 
zeki profile image
Zeki Ahmet Bayar •

Thanks for the post!

Collapse
 
anaroman profile image
Ana Roman •

Thank you for the post, it was really helpful!