版本号必须放在url路径中,如/v1/users;不同版本应使用独立controller并显式注册路由;弃用旧版本需返回410状态码或重定向,并在文档和swagger中标注。

版本号必须放在 URL 路径里,不能放 Header 或 Query
Beego 的路由匹配完全基于路径字符串,Accept 头或 ?v=2 这类方式无法参与路由分发,也无法被 beego.RESTRouter 或中间件统一识别。客户端调用时若依赖 Header 版本,会丢失路由上下文,导致所有版本请求都落到同一个 controller —— 后续只能靠手动解析、分支判断,破坏 RESTful 分层逻辑。
正确做法是把版本作为路径前缀:/v1/users、/v2/users。这样既能被路由系统精准隔离,也符合 OpenAPI 和客户端 SDK 的通用约定。
- ✅ 推荐:
/v1/users、/v2/orders - ❌ 避免:
/users?v=2、/users+Accept: application/vnd.myapi.v2+json - ⚠️ 注意:
/api/v1和/v1是两种风格,项目内必须统一;建议去掉冗余/api,直接用/v1,更简洁且减少嵌套层级
不同版本用不同 Controller,别在一个 Controller 里 if-else
把 v1 和 v2 的逻辑塞进同一个 UserController,靠 c.Ctx.Input.Param(":version") 判断再分支处理,短期看似省事,长期必然失控:字段增删、分页逻辑变更、状态码调整、错误结构演进都会让函数越来越臃肿,测试难覆盖,Git diff 失去意义。
Beego 支持按需注册 controller,天然适合版本隔离:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 定义
v1.UserController和v2.UserController两个独立 struct,各自实现List()、Create()等方法 - 在
routers/router.go中分别注册:beego.RESTRouter("/v1/users", &v1.UserController{})、beego.RESTRouter("/v2/users", &v2.UserController{}) - 共用的 model 层(如
models.User)可复用,但 controller 和 response 结构必须物理隔离
路由注册时禁用 AutoRouter,显式绑定路径与版本
beego.AutoRouter 会扫描所有 controller 并按文件名/方法名自动推导路径,比如把 v2.UserController 映射成 /userv2 或 /v2user,完全不可控,和你写的 /v2/users 不一致 —— 这会导致文档、SDK、前端调用全部失效。
必须关闭 AutoRouter,并在 router.go 中逐条声明:
- 在
main.go或app.conf中确认EnableAutoRouter = false - 每个版本路由都用
beego.RESTRouter或带 method 映射的beego.Router,例如:beego.Router("/v2/users", &v2.UserController{}, "get:List;post:Create") - 路径末尾不加斜杠:
/v2/users✅,/v2/users/❌(两者在 Beego 中是不同路由,容易引发 404)
v1 停止维护后,别删代码,要重定向或返回明确弃用提示
直接删除 /v1 路由会导致存量客户端瞬间 404,运维无感知,问题排查成本极高。Beego 没有内置版本弃用机制,得自己兜底:
- 保留
v1.UserController,但所有方法统一返回c.JSONError(410, "v1 API deprecated. Please upgrade to v2."),状态码用410 Gone而非404,语义更准确 - 或者做 301 重定向:
c.Ctx.Output.SetStatus(301)+c.Ctx.Output.Header("Location", "https://api.example.com/v2/users"),但注意 GET 以外的方法重定向不安全,慎用 - 关键点:弃用策略必须写进文档,并在 Swagger 注解中标注
// @Deprecated true,否则前端根本不知道该切哪版
版本控制最易被忽略的是响应结构一致性 —— v1 返回 {"data": []},v2 改成 {"items": [], "meta": {}},哪怕路径和 controller 分开了,前端依然要写两套解析逻辑。所有版本的 JSON 字段命名、分页格式、错误 code/message 必须在 base controller 层统一封装,不能靠各版本 controller 自由发挥。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










