Golang — Consuming Rest API

Rajkumar soni
5 min readJul 4, 2022

--

Consume RESTful API in GoLang

Today we will see how we can consume the RESTful API in golang. There are thousands of open REST API’s are available out there which we can easily consume.

For this article purpose i will use most known and easily accessible API which is jsonplaceholder. This API have a very simple schema with familiar entities like (posts, comments, todos, users) and it doesn’t enforce any authentication also.

Prerequisites:

I assume that you have your golang setup ready and have basic knowledge in GoLang for this article.

Querying The API

Now we are going to query for user list available on the API. For that we’ll need to hit the https://jsonplaceholder.typicode.com/usersAPI endpoint that returns this. If you open this endpoint in your browser you should see a JSON printing out, which we’ll be expecting as a response when we will performs a GET request on this endpoint.

GET Request

So, in order to implement, what we have just discusses we need to write a program which will perform GET operation with our API.

package main

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

func main() {
response, err := http.Get("https://jsonplaceholder.typicode.com/users")

if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
defer response.Body.Close()
responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(responseData))

}

Now we will breakdown above code:

import:

bytes - This package implements functions for the manipulation of byte slices.

encoding/json - This package contains methods that are used to convert Go types to JSON and vice-versa.

fmt - This package implements formatted I/O functions.

io/ioutil - This package implements some I/O utility functions (For instance, reading the contents of a file , reading from a io.Reader, etc)

log - Has methods for formatting and printing log messages.

net/http - Contains methods for performing operations over HTTP. It provides HTTP server and client implementations and has abstractions for HTTP request, response, headers, etc

main function:

Within our main function we first query our API endpoint using http.Get("https://jsonplaceholder.typicode.com/users"), we map the results of this into either response or err and then check to see if err is nil. If it is we exit.

Below this, we then perform the conversion of our response’s body from bytes into something meaningful that can be printed out in the console.

The defer ensures that the resp.Body.Close() is executed at the end of method . Now, it is extremely important to close the response body. Not doing it will result in resource leaks.

Then we use ioutil.ReadAll(response.Body) to read in data from the incoming byte stream and then convert this []byte response into a string using string(responseData) within our print statement.

Above could will print the list of all users.

Creating users struct:

Now as we got the response which we want and we also know the structure of the response. Now we will create the users struct so that we can map our object to it.

Below is one of the json object which we are getting from GET call. We need to write struct for that.

{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
}

Here we need to write four structs in order to map all the data as below:

type Users []struct {
ID int `json:"id"`
Name string `json:"name"`
Username string `json:"username"`
Email string `json:"email"`
Address Address `json:"address"`
Phone string `json:"phone"`
Website string `json:"website"`
Company Company `json:"company"`
}
type Address struct {
Street string `json:"street"`
Suite string `json:"suite"`
City string `json:"city"`
Zipcode string `json:"zipcode"`
Geo Geo `json:"geo"`
}
type Geo struct {
Lat string `json:"lat"`
Lng string `json:"lng"`
}
type Company struct {
Name string `json:"name"`
CatchPhrase string `json:"catchPhrase"`
Bs string `json:"bs"`
}

Users struct which will map list of users.

Address struct which will map address of particular user.

Geo struct which contain lat and lan of the user’s address.

Company struct which will contain the company detail of the user

json:"id" and all the fields which contain the json is the key we are getting from our response, that will tie which the name like Id which we have mentioned in our struct.

Unmarshalling our JSON:

Now as we’ve defined the structs, we can now Unmarshal the returned JSON string into a new variable. we can do this by using the Golang inbuilt package encoding/json which have json.Unmarshal() method which is used to convert the json(Byte data) into Struct.

 var responseObject Users
json.Unmarshal(responseData, &responseObject)
for index, value := range responseObject {
fmt.Println(index, value.Name)
}

Just we need to add above code in main.go file below the fmt.Println(string(responseData)) line, after that when you run above code you will get the below output in the console:

0 Leanne Graham
1 Ervin Howell
2 Clementine Bauch
3 Patricia Lebsack
4 Chelsey Dietrich
5 Mrs. Dennis Schulist
6 Kurtis Weissnat
7 Nicholas Runolfsdottir V
8 Glenna Reichert
9 Clementina DuBuque

You can download full project from here.

Full Source code:

package mainimport (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
)
type Users []struct {
ID int `json:"id"`
Name string `json:"name"`
Username string `json:"username"`
Email string `json:"email"`
Address Address `json:"address"`
Phone string `json:"phone"`
Website string `json:"website"`
Company Company `json:"company"`
}
type Address struct {
Street string `json:"street"`
Suite string `json:"suite"`
City string `json:"city"`
Zipcode string `json:"zipcode"`
Geo Geo `json:"geo"`
}
type Geo struct {
Lat string `json:"lat"`
Lng string `json:"lng"`
}
type Company struct {
Name string `json:"name"`
CatchPhrase string `json:"catchPhrase"`
Bs string `json:"bs"`
}
func main() {
response, err := http.Get("https://jsonplaceholder.typicode.com/users")
if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(responseData))
var responseObject Users
json.Unmarshal(responseData, &responseObject)
for index, value := range responseObject {
fmt.Println(index, value.Name)
}
}

Conclusion:

In this tutorial, we’ve looked at how we can perform GET requests on HTTP endpoints and print out the plain text response of the response. We’ve then looked at how you can unmarshal the JSON response into struct objects that we can effectively work with as if they were normal objects.

Happy Learning …!!!

--

--