Ask a web server for something with http.Get, close the body, and read the answer as JSON or as raw bytes.
http.Get sends the request and hands back the response as soon as the headers arrive. The body is still open at that point, so close it with defer on the line after the error check.
Skip the close and the connection stays checked out of the pool for the life of the program.
const latestURL = "https://proxy.golang.org/golang.org/x/text/@latest"
resp, err := http.Get(latestURL)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()err covers a request that never completed: no DNS, no route, no answer. A server that replied "404 Not Found" replied, so the status is yours to check.
if resp.StatusCode != http.StatusOK {
log.Fatalf("proxy answered %s", resp.Status)
}resp.Body is an io.Reader, which is what the JSON decoder wants. It reads straight off the connection, so nothing has to be held in memory first.
An anonymous struct is fine for a response you use once. Give it a name when two functions need it.
var latest struct {
Version string
Time time.Time
}
if err := json.NewDecoder(resp.Body).Decode(&latest); err != nil {
log.Fatal(err)
}For a small response that is not JSON, io.ReadAll gives you the whole thing as bytes.
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))A minimal program
This program asks the Go module proxy which version of golang.org/x/text is current, then prints the status, the version, and the day it shipped.
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"time"
)
const latestURL = "https://proxy.golang.org/golang.org/x/text/@latest"
func main() {
resp, err := http.Get(latestURL)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Fatalf("proxy answered %s", resp.Status)
}
var latest struct {
Version string
Time time.Time
}
if err := json.NewDecoder(resp.Body).Decode(&latest); err != nil {
log.Fatal(err)
}
fmt.Println("status: ", resp.Status)
fmt.Println("version: ", latest.Version)
fmt.Println("released:", latest.Time.Format("2 Jan 2006"))
}Run it and you get whichever version is current today. The three lines stay the same.
$ go run main.go
status: 200 OK
version: v0.41.0
released: 11 Aug 2026