golang

Golang HTTP Request

A HTTP request refers to an action performed by an HTTP client on a specific HTTP (protocol) resource. The resource is mainly identified by an URL as a domain name or an IP address.

HTTP requests are one of the most building blocks of the modern web. Using HTTP request, we can request resources such as web pages, videos, images, and other files from a remote server.

In this article, we will learn how to build a basic HTTP client using the Go programming language.

Requirements

In this article, you will need the following resources:

  1. Go compiler installed on your system.
  2. Basic Go knowledge.
  3. A text editor.

HTTP GET

The first method we are going to implement is HTTP GET method. A GET method allows us to request data from a specified resource. For example, when we need to fetch articles from the linuxhint.com server, we use a GET method.

The first step is to ensure you setup your project. If you are not familiar with how to create and work with a go project, check our tutorial on Installing Go.

Once the project is created, open your main go file and import the net/http package from the go standard library.

The net/http package provides us with the functionality and utilities to make HTTP request to remote servers.

Import the net/http package by adding the line below in your go file.

import (
   "net/http"
)

In the net/http package, there is a Get method that allows us to make HTTP GET methods. The function syntax is as shown below:

func Get(url string) (resp *Response, err error)

The function takes an URL as the argument and returns the response as a pointer to the structure and an error (if any).

If the method does not encounter an error, the response returned contains the response body from the requested resource.

To use the Get method, we can create code as shown:

resp, err := http.Get("https://api.spacexdata.com/v4/launches/latest")
    if err != nil {
        log.Fatal(err)
}

In the example above, we call the Get method and pass the URL to the resource we wish to access as a string.

In our example, we use the SpaceX API.

As you will notice, the function returns two values which we store in two variables: resp and err which holds the returned response and the error, respectively.

Keep in mind that the resp contains nothing but a pointer to the struct holding the actual data. Hence, if we try to print it out, we will get a bunch of jumbled data.

An example output from the above request is as shown below:

For us to view the actual data, we need to access the Body property on the struct returned. We then need to read it and print it out to the console, or save it into a file.

For this, we can use the ioutil.ReadMe method. This method is defined in the ioutil package. It returns the response body and an error.

NOTE: After reading the response Body, we need to close it to avoid if from locking other operations in your program.

We can do this by setting the close method to run after the main function is finshed. The defer keyword in Go comes in-hand.

The resp.Body.Close() allows us to close the response body after reading. Once we read the response body, we can print it out to the console as implemented in the code below:

Check out our tutorial on Golang Defer to learn more

package main
import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)
func main() {
    resp, err := http.Get("https://api.spacexdata.com/v4/launches/latest")
    if err != nil {
        log.Fatal(err)
    }
     // close body
     defer resp.Body.Close()
    // read body
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

The above code implements a HTTP client in Go capable of making HTTP GET request to the specified method.

An example return value is as shown:

For better readability, you can format the response into readable-json format or perform Marshal and Unmarshal to select the desired output.

Check our tutorial on JSON Marshal and Unmarshal to learn more.

HTTP POST

The next part of a HTTP client is making POST method. A HTTP method allows you to send data to the server and perform an action on the specified resource. This could create, deleting, or updating a resource.

In Go, we can make POST request using the net/http package. It provides us with the Post method, allowing us to send data to a server.

The function syntax is as shown below:

func Post(url, contentType string, body io.Reader) (resp *Response, err error)

The function takes three arguments:

  1. The address of the resource.
  2. The content type of the body to send to the server, a string
  3. The request body of type io.Reader

The function should then return the response and an error. Keep in mind that we have to convert the data to send to the server into an acceptable format. We can do this by converting the JSON data into Io.Reader, which is basically an interface in Go.

Check the source code to learn more.

Converting JSON data to Io.Reader type involves two steps:

The first is to encode the JSON data into byte format. We can do this by JSON marshaling as discussed in our tutorial.

Once encoded, we can convert the data into type as implemented by io.Reader interface using the NewBuffer method. This method returns the io.Reader type which we can then pass to the Post method.

A sample code block is as shown below:

    body, _ := json.Marshal(map[string]string{
        "id": "1",
        "site": "linuxhint"
    })
    encoded_json := bytes.NewBuffer(body)

Once we have all the parts in order, we can invoke the Post method to the specified resource. Keep in mind that this tutorial uses dummy data and links.

package main
import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)
func main() {
    body, _ := json.Marshal(map[string]string{
        "id": "1",
        "site": "linuxhint"
    })
    resp, err := http.Post("http://example.com/v4/endpoint/post", "application/json", body)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    return_body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(body))
}

The above method implements a simple HTTP client that can make HTTP Post methods to a specified resource.

Conclusion

This article shows you how to build a fundamental HTTP client using the Go programming language. Go is exceptionally fast when it comes to HTTP serving. Using the knowledge in this article, you can expand the client to a fully-fledge application.

Keep coding.

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list