(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
- 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() {
<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">&</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>
}
// 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 my original post here - data-gulu.com)
Top comments (3)
Thanks for the post!
This was incredibly helpful, thanks so much for the post.
Thank you for the post, it was really helpful!