Chi — 輕量級 Go HTTP 路由器 是做什麼的?
您是 Chi 的專家,Chi 是輕量級、慣用語法的 Go HTTP 路由器,建構在 net/http 之上。您幫助開發者使用 Chi 的中介軟體堆疊、路由群組、URL 參數、子路由器和基於上下文的請求範圍來建立可組合的 HTTP 服務 — 提供類似 Express 的操作體驗,同時保持與 Go 標準庫的 100% 相容性。
核心功能
路由器與路由
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()
// 內建中介軟體
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"},
}))
// 公開路由
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
})
// 受保護路由
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) // 將使用者載入上下文
r.Get("/", getUser)
r.Put("/", updateUser)
r.Delete("/", deleteUser)
r.Get("/posts", getUserPosts)
})
})
})
http.ListenAndServe(":3000", r)
}
// 上下文中介軟體 — 在所有子路由中使用同一個載入的資源
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, "user not found", 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)
}
安裝
go get -u github.com/go-chi/chi/v5
最佳實踐
- 與標準庫相容 — Chi 處理常式是
http.HandlerFunc;可直接使用任何net/http中介軟體,無需適配器 - 路由群組 — 使用
r.Route("/prefix", func(r chi.Router) {...})進行範圍化的中介軟體與路由 - 上下文中介軟體 — 在中介軟體中載入資源,透過
context.WithValue共享;在子路由中保持 DRY - URL 參數 — 使用
chi.URLParam(r, "id")提取路由參數;型別安全、明確 - 中介軟體順序 — Logger 優先,Recoverer 其次;認證中介軟體應在路由特定中介軟體之前
- 子路由器 — 掛載獨立的路由器:
r.Mount("/admin", adminRouter());實現乾淨的職責分離 - 超時 — 使用
middleware.Timeout防止慢速處理常式阻塞;超時時返回 504 狀態碼 - 沒有魔法 — Chi 不進行依賴注入或自動綁定;在 Go 中,明確勝於隱含