Building production-grade HTTP clients for crypto exchange APIs.


Fetching URLs

Basic Fetch (http.Get)

resp, err := http.Get(url)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)

Production Fetch (With Timeout)

The default http.Get has no timeout. Always use http.Client with a timeout.

client := &http.Client{
    Timeout: 10 * time.Second,
}
resp, err := client.Get(url)

Custom Headers & Methods

Use http.NewRequest for headers or non-GET methods.

req, err := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer my-token")
resp, err := [client.Do](<http://client.Do>)(req)

HTTP Client Architecture

Transport & Connection Pooling

Fine-tune http.Transport to reuse connections. TLS handshakes are slow; avoid doing one per request.

func newHTTPClient() *http.Client {
    t := &http.Transport{
        MaxIdleConns:        100,
        MaxIdleConnsPerHost: 100,  // Increase for frequent polling
        IdleConnTimeout:     90 * time.Second,
    }
    return &http.Client{
        Transport: t,
        Timeout:   10 * time.Second,
    }
}

Timeout Layers

Setting Recommendation Reason
:--- :--- :---
http.Client.Timeout 10s–30s Hard cap. Kill hung requests.
Transport.ResponseHeaderTimeout 5s–10s Fail fast if server accepts but sends nothing.

Functional Options Pattern