I am a huge fan of the Go programming language and have written a decent amount of material on the subject. For example, a popular tutorial I wrote titled, Create a Simple RESTful API with Golang, focuses on developing an API. However, I recently received questions on the subject of consuming data from other APIs from within a Go application.
We’re going to see how to issue HTTP requests from within Go, in an effort to consume or send data to other RESTful APIs that might exist on the internet.
If you’ve been keeping up with my content, you’ll remember an article I wrote on the subject of unit testing an application that serves RESTful endpoints. Many of those concepts can translate over to what we’re trying to accomplish here.
Take the following Golang code for example:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
fmt.Println("Starting the application...")
response, err := http.Get("https://httpbin.org/ip")
if err != nil {
fmt.Printf("The HTTP request failed with error %s\n", err)
} else {
data, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
}
jsonData := map[string]string{"firstname": "Nic", "lastname": "Raboy"}
jsonValue, _ := json.Marshal(jsonData)
response, err = http.Post("https://httpbin.org/post", "application/json", bytes.NewBuffer(jsonValue))
if err != nil {
fmt.Printf("The HTTP request failed with error %s\n", err)
} else {
data, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
}
fmt.Println("Terminating the application...")
}
The above code is a fully functional application that uses the popular HTTP testing website, httpbin.
Using the Go http package, we can construct several different requests. In our example we are sending a GET request as well as a POST request. Regardless of the request type, we are expecting that a response comes back. If we wish to see the response body, and we do, we need to read from it and get it in a format that is easier to work with.
Things are a little different when it comes to POST requests.
When sending a POST request, the data body can be in several different formats. When working with RESTful API services, the common format is JSON, but form data is also popular.
jsonData := map[string]string{"firstname": "Nic", "lastname": "Raboy"}
jsonValue, _ := json.Marshal(jsonData)
response, err = http.Post("https://httpbin.org/post", "application/json", bytes.NewBuffer(jsonValue))
If we choose to send JSON data, we need to marshal it into an array of bytes. We also need to define in the header that we are sending JSON data, just in case the recipient doesn’t make assumptions.
This is not the only way to make HTTP requests with Golang. On Stack Overflow, a developer pointed out the following solution:
jsonData := map[string]string{"firstname": "Nic", "lastname": "Raboy"}
jsonValue, _ := json.Marshal(jsonData)
request, _ := http.NewRequest("POST", "https://httpbin.org/post", bytes.NewBuffer(jsonValue))
request.Header.Set("Content-Type", "application/json")
client := &http.Client{}
response, err := client.Do(request)
if err != nil {
fmt.Printf("The HTTP request failed with error %s\n", err)
} else {
data, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
}
In the above code we are still marshaling a JSON value, but this time we are constructing a request in multiple steps and then issuing the request with an HTTP client. I think my initial approach is a little more elegant, but both will get you to the same place.
You just saw how to issue HTTP requests from within your Golang application to RESTful API endpoints that might exist. This is useful if you’re creating a web application and need to consume data such as social media information.
If you’re interested in learning how to create your own RESTful API with Go, check out the, very popular, previous tutorial I had written on the subject.
A video version of this article can be seen below.