go-chi-rest-api

test12026-10-2516 次阅读

为什么选 chi

标准库 net/http 功能够用,但路由没有路径参数、没有分组。chi 在保持 net/http 接口不变的前提下,补齐了这些能力,中间件也是标准的 func(http.Handler) http.Handler,迁移成本很低。

基础路由与中间件

chi 内置了一批常用中间件,RequestID、RealIP、Logger、Recoverer 一行一个挂上即可。

package main

import (
	"net/http"
	"time"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
)

func main() {
	r := chi.NewRouter()
	r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Use(middleware.Logger)
	r.Use(middleware.Recoverer)
	r.Use(middleware.Timeout(30 * time.Second))

	r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("ok"))
	})

	http.ListenAndServe(":8080", r)
}

路由分组与路径参数

Route 把一组路径收进同一个前缀,路径参数用花括号声明,读取时走 chi.URLParam,比自己切字符串稳。

	r.Route("/articles", func(r chi.Router) {
		r.Get("/", listArticles)      // GET  /articles
		r.Post("/", createArticle)    // POST /articles
		r.Get("/{id}", getArticle)    // GET  /articles/42
		r.Put("/{id}", updateArticle) // PUT  /articles/42
	})

func getArticle(w http.ResponseWriter, r *http.Request) {
	id := chi.URLParam(r, "id")
	w.Write([]byte(id))
}

自定义中间件

中间件就是包一层 http.Handler,签名和标准库完全一致,所以任何 net/http 中间件都能直接拿来用。

func AuthMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		token := r.Header.Get("Authorization")
		if token == "" {
			http.Error(w, "unauthorized", http.StatusUnauthorized)
			return
		}
		next.ServeHTTP(w, r)
	})
}

// 挂在分组上,只保护写接口
r.Route("/articles", func(r chi.Router) {
	r.Use(AuthMiddleware)
	r.Post("/", createArticle)
	r.Put("/{id}", updateArticle)
})

几点提醒

  • 中间件按注册顺序由外到内包裹,越早注册越先执行。
  • URLParam 取不到时返回空串,业务上要先校验。
  • 因为 handler 仍是标准 http.Handler,之后想换 http.Server 做优雅关闭也不用改路由层。
T

test1

文章作者

为什么选 chi 标准库 net/http 功能够用,但路由没有路径参数、没有分组。chi 在保持 net/http...

分类
技术
发布时间
2026-10-25
字数
约 1671 字
阅读
16 次