旧路径必须显式注册路由 handler,不能依赖中间件兜底;重定向须用 http.redirect 并选 307/308 保留方法和 body;仅适用于路径变更,字段兼容需在新 handler 中处理。

旧路径必须显式注册 handler,不能靠中间件兜底
路由层不识别旧路径,请求直接 404;中间件在匹配到 handler 后才执行,此时已错过拦截时机。动态重定向的前提是:旧路径能进到你的代码里。
实操建议:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 用
gorilla/mux或gin.Engine时,对每个旧路径调用r.HandleFunc("/v1/users", ...)或r.GET("/v1/users", ...)显式注册 - 不要写成
r.Use(redirectMiddleware)试图统一转发——它对未注册路径完全无效 - 若旧路径量大,可用 map 预置映射关系,循环注册,避免硬编码爆炸
重定向必须用 http.Redirect,不能手动写状态码+Location
只写 resp.WriteHeader(http.StatusMovedPermanently) 和 resp.Header.Set("Location", "/v2/users") 会漏掉关键步骤:响应体未清空、Content-Type 未重置、相对路径未解析,部分客户端(尤其是 iOS WebView)会忽略这种“伪重定向”。
实操建议:
- 一律使用
http.Redirect(w, r, "/v2/users", http.StatusMovedPermanently) - 目标 URL 可为相对路径(如
"/api/v2/users"),http.Redirect内部会自动基于r.URL拼出完整地址 - 若反向代理后
r.Host不可靠,需提前修正r.URL.Scheme,否则跳转可能变成http://...即使实际是 HTTPS
301/302 会改方法,POST 请求重定向后变 GET 且丢 body
旧客户端发的是 POST /v1/users 带 JSON body,301/302 重定向后,浏览器或多数 HTTP 客户端会以 GET /v2/users 重发,body 消失,服务端收不到数据。
实操建议:
- 对非 GET/HEAD 请求,改用
http.StatusPermanentRedirect (308)或http.StatusTemporaryRedirect (307) - 308 要求客户端严格保留原方法和 body,兼容性比 307 更好(HTTP/1.1 标准支持)
- 别依赖客户端“应该懂”,实测 Android OkHttp、iOS NSURLSession 对 302 的 POST 处理极不一致
禁止用重定向代替兼容逻辑,尤其涉及字段变更
重定向只解决路径和方法问题,不解决请求体结构、字段增删、类型变化。比如旧客户端传 {"name": "a"},新接口要求 {"full_name": "a", "updated_at": "..."},308 也救不了。
实操建议:
- 重定向仅用于路径变更(
/v1/x→/v2/x)或方法微调(GET /users?id=1→GET /users/1) - 字段级兼容必须在新 handler 内做:用指针字段 +
omitempty、双字段过渡、手动映射解析 - 记录
X-Deprecated: true响应头和访问日志,倒逼客户端升级,而非无限兜底
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










