Noções básicas de net/http
9 exemplos para você começar com net/http - 7 básicos e 2 intermediários.
Busque em todas as páginas da documentação
9 exemplos para você começar com net/http - 7 básicos e 2 intermediários.
mkdir httplab && cd httplab && go mod init example.com/httplab.main.go (ou arquivos separados em um mesmo pacote) e execute com go run ..Uma função com a assinatura func(http.ResponseWriter, *http.Request) pode servir HTTP diretamente.
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello")
})
http.ListenAndServe(":8080", nil)
}http.HandleFunc registra no http.DefaultServeMux.nil para ListenAndServe usa esse mux padrão.ServeMux dedicado em serviços reais para evitar colisões de rotas globais.Relacionado: net/http: A Pilha HTTP "Batteries-Included" do Go - visão geral conceitual
Isole rotas em um mux que você possui, em vez do padrão global.
package main
import (
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
})
http.ListenAndServe(":8080", mux)
}http.NewServeMux() retorna um roteador vazio.ListenAndServe.Relacionado: Padrões de Servidores HTTP, Handlers e ServeMux - padrões do Go 1.22+
Registre rotas com método HTTP e segmentos {param} em uma única chamada.
package main
import (
"fmt"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /users/{id}", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "user=%s", r.PathValue("id"))
})
http.ListenAndServe(":8080", mux)
}"METHOD /path/{name}" no Go 1.22 e posterior.r.PathValue("id") lê os segmentos capturados.Relacionado: Padrões de Servidores HTTP, Handlers e ServeMux - padrões de roteamento
Defina cabeçalhos antes de escrever o corpo; o primeiro Write envia os cabeçalhos implicitamente.
package main
import (
"net/http"
)
func main() {
http.HandleFunc("/json", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"ok":true}`))
})
http.ListenAndServe(":8080", nil)
}WriteHeader apenas uma vez por resposta.Header().Set é canonizado em maiúsculas/minúsculas pelo net/http.http.Error para respostas de erro rápidas em texto simples.Decodifique JSON de r.Body e sempre feche o que você abre no lado do cliente.
package main
import (
"encoding/json"
"io"
"net/http"
)
type Payload struct {
Name string `json:"name"`
}
func main() {
http.HandleFunc("/echo", func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
var p Payload
if err := json.NewDecoder(r.Body).Decode(&p); err != nil && err != io.EOF {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
json.NewEncoder(w).Encode(p)
})
http.ListenAndServe(":8080", nil)
}r.Body deve ser lido ou fechado para reutilizar conexões keep-alive.http.MaxBytesReader em handlers de produção.json.NewDecoder para streaming de payloads grandes.Chamadas de saída devem usar um cliente com timeout e cancelamento de contexto.
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, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://example.com", nil)
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
b, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, len(b))
}http.Get em servidores; ele usa http.DefaultClient sem timeout.defer resp.Body.Close() para retornar conexões ao pool.NewRequestWithContext vincula a chamada ao cancelamento do chamador.Relacionado: Clientes HTTP, Transporte e Pooling de Conexões - ajuste de transporte
Middleware envolve um handler interno e executa código antes ou depois dele.
package main
import (
"log"
"net/http"
"time"
)
func logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start))
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/work", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("done"))
})
http.ListenAndServe(":8080", logging(mux))
}func(http.Handler) http.Handler.ListenAndServe, não o handler interno nu.Relacionado: Cadeias de Middleware e Contexto de Requisição - cadeias e valores
Configure timeouts em http.Server em vez de ListenAndServe nu.
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("api"))
})
srv := &http.Server{
Addr: ":8080",
Handler: mux,
ReadHeaderTimeout: 5 * time.Second,
IdleTimeout: 60 * time.Second,
}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
_ = srv.Shutdown(ctx)
}ReadHeaderTimeout mitiga ataques do tipo slowloris baseados em cabeçalhos.Shutdown descarrega requisições em andamento durante implantações.main possa lidar com sinais.Relacionado: Lista de Verificação de Configuração de Produção net/http - lista completa de produção
Teste handlers em memória sem abrir uma porta TCP.
package main
import (
"net/http"
"net/http/httptest"
"testing"
)
func greet(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hi"))
}
func TestGreet(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/greet", nil)
rec := httptest.NewRecorder()
greet(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status=%d", rec.Code)
}
if rec.Body.String() != "hi" {
t.Fatalf("body=%q", rec.Body.String())
}
}httptest.NewRecorder implementa http.ResponseWriter e grava status/corpo.httptest.NewRequest constrói um *http.Request com corpo opcional.Relacionado: httptest para Testes de Integração de Handlers - padrões de teste mais completos
Versões da Pilha: Esta página foi escrita para Go 1.26.x (padrão Green Tea GC, go fix modernizers - verifique o patch na compilação), chi (última versão - verifique na compilação), gin (última versão - verifique na compilação), echo (última versão - verifique na compilação), google.golang.org/grpc (última versão - verifique na compilação), sigs.k8s.io/controller-runtime (última versão - verifique na compilação), kubebuilder (última versão - verifique na compilação), tinygo (última versão - verifique os alvos de placa na compilação), wazero (última versão - verifique na compilação) e golangci-lint (última versão - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 18 de jul. de 2026