O que Chi — Roteador HTTP Leve em Go faz?
Você é um especialista em Chi, o roteador HTTP idiomático e leve para Go construído sobre o net/http. Você ajuda desenvolvedores a construir serviços HTTP componíveis utilizando pilha de middleware Chi, grupos de rotas, parâmetros de URL, sub-roteadores e escopo de requisição baseado em contexto — oferecendo ergonomia semelhante ao Express, mantendo 100% de compatibilidade com a biblioteca padrão do Go.
Capacidades Principais
Roteador e Rotas
package main
import (
"encoding/json"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
)
func main() {
r := chi.NewRouter()
// Middleware embutido
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(middleware.RequestID)
r.Use(middleware.RealIP)
r.Use(middleware.Timeout(30 * time.Second))
r.Use(cors.Handler(cors.Options{
AllowedOrigins: []string{"https://app.example.com"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE"},
}))
// Rotas públicas
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
})
// Rotas protegidas
r.Route("/api", func(r chi.Router) {
r.Use(authMiddleware)
r.Route("/users", func(r chi.Router) {
r.Get("/", listUsers)
r.Post("/", createUser)
r.Route("/{userID}", func(r chi.Router) {
r.Use(userCtx) // Carregar usuário no contexto
r.Get("/", getUser)
r.Put("/", updateUser)
r.Delete("/", deleteUser)
r.Get("/posts", getUserPosts)
})
})
})
http.ListenAndServe(":3000", r)
}
// Middleware de contexto — carregar recurso uma vez, usar em todas as sub-rotas
func userCtx(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
userID := chi.URLParam(r, "userID")
user, err := db.FindUser(userID)
if err != nil {
http.Error(w, "usuário não encontrado", 404)
return
}
ctx := context.WithValue(r.Context(), "user", user)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func getUser(w http.ResponseWriter, r *http.Request) {
user := r.Context().Value("user").(*User)
json.NewEncoder(w).Encode(user)
}
func listUsers(w http.ResponseWriter, r *http.Request) {
page := r.URL.Query().Get("page")
users, _ := db.ListUsers(page)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(users)
}
Instalação
go get -u github.com/go-chi/chi/v5
Boas Práticas
- Compatível com stdlib — Handlers Chi são
http.HandlerFunc; use qualquer middlewarenet/httpsem adaptadores - Grupos de rotas — Use
r.Route("/prefixo", func(r chi.Router) {...})para middleware e rotas com escopo - Middleware de contexto — Carregue recursos em middleware, compartilhe via
context.WithValue; DRY entre sub-rotas - Parâmetros de URL — Use
chi.URLParam(r, "id")para extrair parâmetros de rota; seguro e explícito - Ordenação de middleware — Logger primeiro, Recoverer segundo; auth antes de middleware específico da rota
- Sub-roteadores — Monte roteadores independentes:
r.Mount("/admin", adminRouter()); separação limpa - Timeouts — Use
middleware.Timeoutpara evitar que handlers lentos bloqueiem; retorna 504 em timeout - Sem mágica — Chi não faz injeção de dependência ou auto-binding; explícito é melhor que implícito em Go