An HTTP client that gives up in Go
A shared client with a timeout, and a request carrying a context.
var client = &http.Client{Timeout: 10 * time.Second}
func fetch(ctx context.Context, url string) (int, string, error) {
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return 0, "", fmt.Errorf("build request: %w", err)
}
request.Header.Set("Accept", "application/json")
response, err := client.Do(request)
if err != nil {
return 0, "", fmt.Errorf("get %s: %w", url, err)
}
defer response.Body.Close()
body, err := io.ReadAll(io.LimitReader(response.Body, 1<<20))
if err != nil {
return response.StatusCode, "", fmt.Errorf("read body: %w", err)
}
return response.StatusCode, string(body), nil
}
How it works
- Never use http.DefaultClient in production: it has no timeout.
NewRequestWithContextis what makes cancellation work.- Close the body, always, and drain it if you reuse the connection.
Keywords and builtins used here
defererrorfuncifintreturnstringvar
The run, in numbers
- Lines
- 21
- Characters to type
- 638
- Tokens
- 175
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 95 seconds.
Step 5 of 5 in HTTP, step 20 of 26 in Standard library & project layout.