最简API版本控制是直接在app.Get、app.Post等路径前加/v1/或/api/v2/,用Party分组实现路由隔离与中间件按需挂载,避免query或header方式导致日志、文档混乱。

用路由前缀实现最简API版本控制
直接在 app.Get、app.Post 等方法的路径前加 /v1/ 或 /api/v2/ 是 Iris 里最常用也最稳妥的做法。Iris 本身不内置“版本控制器”概念,靠的是路由分组 + 路径隔离,避免后期改逻辑时互相污染。
常见错误现象:把版本号写进 query(如 /users?id=1&version=v2)或 header(如 Accept: application/vnd.myapp.v2+json),结果导致中间件难统一处理、日志难归类、OpenAPI 文档生成混乱。
- 推荐写法:
app.Get("/v1/users", handlerV1)和app.Get("/v2/users", handlerV2) - 更清晰的组织方式是用
app.Party分组:v1 := app.Party("/v1"),然后v1.Get("/users", ...) - 注意:不同版本的路由不能共用同一组中间件(比如 v2 加了新鉴权字段),需显式按组挂载
Party 分组 + 共享中间件的版本隔离实践
Party 不只是路径前缀封装,它能继承父应用的配置,也能覆盖局部行为——这才是版本控制真正需要的灵活性。
使用场景:v1 用 JWT 验证,v2 改用 OAuth2;但两者共享日志、压缩、CORS 中间件。
- 先注册公共中间件:
app.Use(iris.Compression, middleware.CORS()) - 再创建分组并挂载专属中间件:
v2 := app.Party("/v2").Use(auth.OAuth2Middleware) - 分组内注册路由:
v2.Get("/orders", orderHandlerV2) - ⚠️ 容易踩的坑:
Party创建后没调.Use(),结果 v2 没走任何认证中间件,接口裸奔
如何让 v1 和 v2 复用同一套 handler 逻辑?
不是所有版本都要重写业务逻辑。多数时候只是请求参数校验、响应结构、错误码格式变了,核心处理函数可以复用。
性能影响:直接复用函数体比反射调用或泛型包装快得多,Iris 的 Context 本身已支持多版本适配所需的上下文信息提取。
- 提取公共逻辑为普通 Go 函数:
func handleOrderCreation(ctx iris.Context, version string) - v1 路由中调用:
handleOrderCreation(ctx, "v1") - v2 路由中调用:
handleOrderCreation(ctx, "v2") - 响应格式差异可通过
ctx.JSON()前的结构体选择来隔离,比如v1OrderResponse和v2OrderResponse
OpenAPI 文档怎么体现多个 API 版本?
Iris 自身不生成 OpenAPI,但配合 swaggo/swag 或 getkin/kin-openapi 可以按 Party 分组导出独立文档。关键点在于:每个 Party 必须有唯一 BasePath,否则 Swagger UI 会把 v1/v2 接口混在一起。
容易被忽略的地方:如果你用 swag init -g main.go,它默认只扫描全局路由,不会自动识别 Party 内部的注释。必须确保注释写在分组内 handler 上,并用 // @Router /v2/users [get] 显式声明带版本的路径。
- 示例注释:
// @Router /v2/users [get]+// @Success 200 {array} v2UserResponse - 生成命令要加
-o ./docs/v2单独输出目录,避免覆盖 - 最终部署时,把
/docs/v1/swagger.json和/docs/v2/swagger.json分别挂到不同静态路由下


















