Go by Example

HTTP Client

Set a client timeout or request context deadline to bound HTTP calls, and reuse clients to share connections.

The net/http package provides HTTP clients. Reuse an http.Client so connections can be reused; set a client timeout or a request context deadline to bound each call.

Use a request context for caller cancellation and a client timeout for an overall bound. Close every response body after receiving a response.

package main
 
import (
    "context"
    "fmt"
    "io"
    "net/http"
    "time"
)
 
func main() {
    client := &http.Client{Timeout: 5 * time.Second}
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()
 
    req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://example.com", nil)
    if err != nil {
        panic(err)
    }
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println(resp.StatusCode, len(body))
}

In production

The package-level http.Get uses a client with no overall timeout. Bound response body size when the remote server is not trusted. Read response bodies to EOF and close them when practical so the transport can reuse connections; check the status code because non-2xx responses are not returned as request errors.

Enjoyed this? Get more software craft delivered to your inbox.