Go可用net/http+中间件+httputil.NewSingleHostReverseProxy构建轻量API网关,核心在于路由分发、请求改写与错误统一处理,需手动设置Director、复用Transport、显式处理hop-by-hop头,并结合gorilla/mux等实现路径匹配与中间件链。
Go 本身不提供开箱即用的“API网关”组件,但用 net/http + 中间件 + 反向代理即可构建轻量、可控、高性能的 API 网关——关键不在框架,而在路由分发、请求改写和错误统一处理的设计。
用 httputil.NewSingleHostReverseProxy 实现基础反向代理
这是 Go 构建网关最核心的起点。它不是装饰器或插件,而是一个可定制的 http.Handler,能将请求透传到后端服务并回传响应。
- 必须手动设置
Director函数,否则Host头不会被重写,后端可能拒绝请求 -
Transport建议复用(如全局&http.Transport{}),避免 DNS 缓存缺失和连接池耗尽 - 默认不转发
Connection、Keep-Alive等 hop-by-hop 头,需在ModifyResponse中显式添加
proxy := httputil.NewSingleHostReverseProxy(&url.URL{Scheme: "http", Host: "localhost:8081"})
proxy.Director = func(req *http.Request) {
req.Header.Set("X-Forwarded-For", clientIP(req))
req.Host = "backend-service"
}
用 gorilla/mux 或原生 http.ServeMux 做路径级路由分发
网关的核心职责是“按规则把不同路径的请求打到不同后端”,不是所有流量都走同一个 proxy。这时候需要路由匹配能力。
-
http.ServeMux只支持前缀匹配(/api/users/),不支持通配符或正则,适合简单场景 -
gorilla/mux支持{id:[0-9]+}这类变量提取,方便做路径重写(比如把/v1/users/{id}改成/users?id={id}) - 避免在路由中嵌套太多中间件逻辑;先路由,再进 proxy 的中间件链,职责更清晰
在 proxy handler 前后插入中间件统一处理鉴权、限流、日志
所有经过网关的请求,都应该在进入反向代理前完成身份校验,在返回响应后记录延迟与状态码。