External API Request using Golang HTTP Client

In this article, we will learn how to make external API requests in Golang using HTTP client in a simple way. We will be using a few packages and an endpoint from reqres.in which name is single-user.

Required Packages

  • Format package (fmt) would help us to print data into the console.
  • Log package’s Fatal method would help us to terminate the app in case of failure.
  • net/http makes external HTTP requests, that’s what we need in this article.
  • The unmarshal() method from encoding/json package would decode the JSON to the struct.

Required Endpoint That Should Return Json Data Array

We will be using single-user endpoint in Golang HTTP client request.  According to documentation, it returns the following JSON response,

{
    "data": {
        "id": 2,
        "email": "janet.weaver@reqres.in",
        "first_name": "Janet",
        "last_name": "Weaver",
        "avatar": "https://reqres.in/img/faces/2-image.jpg"
    },
    "support": {
        "url": "https://reqres.in/#support-heading",
        "text": "To keep ReqRes free, contributions towards server costs are appreciated!"
    }
} 

This JSON array has two child arrays, which are data and support. Each has multiple objects.

Create Struct For JSON

In the next step, we will be declaring a struct for JSON. It would parse the JSON into the data structure. Let’s declare it,

type SingleUser struct{

}

Struct name should be following the camel case naming convention. The name SingleUser is suitable and relevant, as it will using for single-user API.

type SingleUser struct {
	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"`
}

The single-user struct has two child structs, which are Data and Support. Each struct has the same fields as the API has.

Get Started

Above, we have discussed resources that we need to make external API requests in Golang using an HTTP client. Now let’s start by importing packages to Golang’s file, below is an example

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

This would import all packages that are mentioned in the import keyword.

response, apiError := http.Get("https://reqres.in/api/users/2")

    if apiError != nil {
        log.Fatal(apiError)	
    }
	
defer response.Body.Close()

The first line of the above script sends the request to the endpoint and assigns values to the variables. The second line has an if-statement that checks if the request’s response has an error. In case of error, it would terminate the app. In the last line, the script closes the connection. It is recommended that the connection should be closed after checking the errors.

body, err := ioutil.ReadAll(response.Body)

response.Body has JSON data that comes from the endpoint and ioutil.ReadAll() helps to read it. Then it assigns to body and error variables.

var user SingleUser 

The user is a variable that is created for single user struct.

err = json.Unmarshal(body, &user)
if err != nil {
   panic(err.Error())
}

Next, json.Unmarshal() decodes the data from JSON data (that we have in body variable) to the SingleUser struct. In this way, the external API request has been completed. To check out the responses following script would help.

fmt.Printf("Results: %v\n", user)

This scripts prints all values from fetched JSON data into the console.

fmt.Println(user.Data.Email)

To print the email in the console, the email object needs to pass in the format Println functions. Above is an example. In last, we have shared the entire page code.

package main

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

type SingleUser struct {
	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() {
   	response, apiError := http.Get("https://reqres.in/api/users/2")

	if apiError != nil {
        log.Fatal(apiError)	
    }
	
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	var user SingleUser 
    err = json.Unmarshal(body, &user)
    if err != nil {
        panic(err.Error())
    }

	fmt.Println(user.Data.Email)
	fmt.Println(user.Data.FirstName)
    fmt.Printf("Results: %v\n", user)
}