About

This post documents how to make HTTP requests with the Go programming language and its standard library.

Background

The Go programming language provides a rich standard library that includes the net/http package for the implementation of HTTP clients and servers.

This post focuses on how to make HTTP requests with the net/http package, and in particular it focuses on a subset of functionality that is centered around http.NewRequest and http.DefaultClient.Do.

The former creates a new request type and the latter sends the request over the wire then returns a response. I prefer this combination of methods because it provides full control over the request before it is sent.

Experiment

Context

The http.NewRequest method returns a new http.Request type that represents a HTTP request. The request object can be bound to a particular HTTP verb (eg GET), a set of headers, and a request body (if applicable).

The request verb is given as the first argument, the URL as the second argument, and an optional body as the third argument. The body is expected to implement the io.Reader interface and in the case of a GET request, the body is typically nil.

The request headers can be configured separately by modifying the req.Header field after the request object has been created. The example sets the User-Agent header. After the request object is fully configured, it can be sent using the http.DefaultClient.Do method, which takes the request object as an argument and returns a response object:

package main

import (
  "fmt"
  "io"
  "net/http"
)

func main() {
  req, err := http.NewRequest("GET", "https://clean.myip.wtf/json", nil)
  if err != nil {
    panic(err)
  }
  req.Header.Set("User-Agent", "my-cool-agent/1.0")

  res, err := http.DefaultClient.Do(req)
  if err != nil {
    panic(err)
  }
  defer res.Body.Close()

  body, err := io.ReadAll(res.Body)
  if err != nil {
    panic(err)
  }
  fmt.Println(string(body))
}

Explanation

Conclusion

The Go programming language provides a rich standard library for making HTTP requests. The combination of http.NewRequest and http.DefaultClient.Do provides a flexible way to create and send HTTP requests with full control over the request parameters.