Basic Go HTTP Requests

September 01, 2019

The http.Client type has two kinds of method attached to it: Do and everything else. The everything else category includes:

The above are preconfigured and cannot be modified, but are easy to use:

package main

import "net/http"

response, _ := http.Get("https://www.google.com")
defer resp.Body.Close()
// Do something with the response

Under the hood, this is calling what you’ll likely be using yourself: http.NewRequest and http.Do.

These allow you to customize the structure of your requests:

package main

import (
  "net/http"
  "net/url"
)

// Create an HTTP client with a connection timeout
var client = &http.Client{
  Timeout: time.Second * 5,
}

request, err := http.NewRequest("GET", "https://www.google.com", nil)
if err != nil {
  return "", err
}

// Add "?id=1"
queryString := url.Values{}
queryString.Add("id", 1)
request.URL.RawQuery = queryString.Encode()

response, _ := client.Do(request)
defer resp.Body.Close()
// More something here

Posting a Form

Here’s how you can POST a form using http.NewRequest and http.Do:

package main

import (
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"
)

func main() {
  // We define our own client so we can play with things
	client := &http.Client{
		Timeout: 5 * time.Second,
	}

  // We start by building a query string (e.g. param1=value&param2=value)
	body := url.Values{}
	body.Add("param1", "value") // Add adds a new header. To update, we'd use Set
	body.Add("param2", "value")
	body.Add("param3", "value")

  // Build the request
	req, _ := http.NewRequest("POST", "https://webhook.site/da76fc7a-873c-4994-93da-e42728c753aa", strings.NewReader(body.Encode())) // We need to use strings.NewReader to satisfy the io.Reader type

  // Add a few headers. Content-Length is automatically populated.
	req.Header.Add("Test", "Value")
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

  // Finally we send the request
	resp, _ := client.Do(req)
	defer resp.Body.Close()
	// Something happens
}

References