Go by Example: HTTP Client
Go 1.23
Perform HTTP requests in Go using the `net/http` package. This example demonstrates how to perform GET requests, set custom headers, parse response bodies, and properly manage resources by closing response bodies.
Code
package main
import (
"bufio"
"fmt"
"net/http"
)
func main() {
// Issue a basic GET request
resp, err := http.Get("https://gobyexample.com")
if err != nil {
panic(err)
}
// Important: Close the response body when finished
defer resp.Body.Close()
fmt.Println("Response status:", resp.Status)
// Print the first 5 lines of the response body
scanner := bufio.NewScanner(resp.Body)
for i := 0; scanner.Scan() && i < 5; i++ {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
panic(err)
}
}Explanation
The net/http package provides a production-grade HTTP client. While helper functions like http.Get are convenient for scripts, they use the http.DefaultClient which has no timeout. This can cause your application to hang indefinitely if the server stops responding.
Best practices for HTTP Clients:
- Always set a Timeout: Create a custom
&http.Client{Timeout: 10 * time.Second}to ensure requests fail fast if the server is slow. - Close the Body: You MUST close
resp.Body(usually viadefer) to avoid leaking network connections and file descriptors. - Use Context: Use
http.NewRequestWithContextto enable cancellation and per-request timeouts that propagate through your call stack.
Code Breakdown
10
http.Get issues a GET request to the specified URL. It follows redirects by default.
15
Deferring Body.Close() is the standard pattern to ensure we don't leak resources. This must be done even if we don't read the whole body.
20
Using a bufio.Scanner is a convenient way to read the response body line by line.

