chi适合作为go网关主路由层,因其轻量、无反射、支持中间件链和嵌套路由,但需手动处理options预检、重写notfound/methodnotallowed为json格式、严格控制中间件顺序(如recoverer→logger→ratelimit→auth→stripprefix),并用reverseproxy+serverbasecontext安全转发请求。

chi 确实适合做 Go 网关的主路由层——它轻量、无反射、支持中间件链和嵌套路由,但直接套用默认模式容易在网关场景下踩坑:比如路径匹配不严格、中间件顺序错乱、或对 http.Handler 透传理解偏差导致上游服务被绕过。
为什么不能直接用 chi.NewRouter() 当网关入口
网关的核心职责是转发、鉴权、限流、日志,不是单纯响应请求。直接用裸 chi.Router 会忽略两个关键点:一是未显式处理 OPTIONS 预检(尤其跨域场景),二是未统一拦截 404 和 405 并转为标准网关错误格式(如 JSON 错误体)。
- 必须包裹一层
http.Handler实现,用于兜底错误处理和 header 标准化 -
chi.Router默认不自动处理OPTIONS,需手动注册或启用chi.Middlewares中的MethodOverride或自定义预检中间件 - 所有子路由应通过
r.Group()统一挂载中间件,避免在每个Get/Post上重复写
如何正确注册下游服务路由(带路径前缀与反向代理)
网关要将 /api/v1/users/... 转发到用户服务,不能只靠 r.Get("/api/v1/users/{id}", ...) 去硬编码 handler;得用 httputil.NewSingleHostReverseProxy + chi.ServerBaseContext 改写目标 URL。
- 用
r.With(...).Route("/api/v1/users", func(r chi.Router) { ... })划定作用域,避免前缀污染全局路由 - 转发 handler 必须重写
req.URL.Host和req.URL.Scheme,否则后端收到的是网关地址而非真实服务地址 - 建议封装一个
proxyHandler(targetURL string)函数,内部调用Director修改req.URL,并设置X-Forwarded-*头 - 别忘了调用
rp.Transport = &http.Transport{...}设置超时和 TLS 配置,否则默认 30s 连接超时可能卡住整个网关
中间件顺序怎么排才不影响转发逻辑
网关中间件顺序决定行为是否生效——比如日志中间件如果放在鉴权之后,失败请求就记不到原始路径;而限流器若在路径解析前执行,就无法按服务维度区分统计。
- 推荐顺序:
Recoverer→Logger→RequestID→RealIP→RateLimit→Auth→StripPrefix(仅对代理路由)→RedirectTrailingSlash -
StripPrefix必须在Auth之后、实际代理 handler 之前,否则鉴权看到的是带前缀的路径,而代理看到的是已剥离的路径,两者不一致 - 所有中间件函数签名必须是
func(http.Handler) http.Handler,不能返回chi.Router或其它类型,否则r.Use()会静默失效
为什么 chi.Mux 的 NotFound 和 MethodNotAllowed 一定要重写
默认的 chi 404 响应是纯文本,且不带 Content-Type: application/json,网关必须输出结构化错误,否则前端无法统一解析。
- 调用
r.NotFound(...)注册自定义 handler,返回map[string]string{"error": "not_found", "path": r.URL.Path}并设 status 404 -
r.MethodNotAllowed(...)同理,补充Allowheader,例如w.Header().Set("Allow", "GET,POST,PUT") - 注意:这两个 handler 只对
chi.Router内部匹配失败生效;若你用了http.StripPrefix后再交给chi,需确保 strip 后路径仍能被路由识别,否则会落到最外层 net/http 的默认 404
真正麻烦的不是写路由,而是让每个中间件都清楚自己操作的是原始请求还是已改写的代理请求——尤其是修改 req.Header 或 req.URL 的中间件,一旦顺序或作用域错位,就会出现 header 丢失、路径错乱、甚至循环代理。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











