Parse JSON API response in Go

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
  • Get JSON response from sample API hosting site - reqres
  • Generate go struct from the response - json-to-go
  • Unmarshal JSON response to go struct
  • 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
    }
    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!"}}
    Convert JSON response
    You can go to this site - JSON to go to convert JSON response to Go struct very easily.
    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))
    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"
        }
        ]
    }
    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)
    }
    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() {
    
        // Get request
        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
    
        var result Response
        if err := json.Unmarshal(body, &result); err != nil {  // Parse []byte to the go struct pointer
            fmt.Println("Can not unmarshal JSON")
        }
    
        // fmt.Println(PrettyPrint(result))
    
        // Loop through the data node for the FirstName
        for _, rec := range result.Data {
            fmt.Println(rec.FirstName)
        }
    }
    
    // PrettyPrint to print struct in a readable way
    func PrettyPrint(i interface{}) string {
        s, _ := json.MarshalIndent(i, "", "\t")
        return string(s)
    }
    Demo
    You can find the original post on my site - Here

    28

    This website collects cookies to deliver better user experience

    Parse JSON API response in Go