接口升级向后兼容的核心是“旧代码不改、旧客户端不崩、旧调用不报错”:小粒度拆分接口、禁止修改已有接口、新增能力用嵌套组合;结构体字段必用指针+omitempty;HTTP路由采用/v1//v2/物理隔离;废弃功能加日志与响应头监控,渐进下线。

接口升级时保证向后兼容,核心是“旧代码不改、旧客户端不崩、旧调用不报错”。Go 语言没有接口版本语法,一切靠设计约束和工程习惯来兜底。
接口定义:小粒度拆分 + 新增不修改
不要在一个大接口里不断加方法。比如把 UserAPI 拆成 UserReader、UserWriter、UserNotifier 等独立接口。v2 新增通知能力,就定义新接口 UserNotifier,老代码继续用 UserReader,完全不受影响。
- 禁止给已有公开接口添加方法——否则所有旧实现编译失败
- 废弃功能不删方法,保留签名,内部返回
errors.New("deprecated")并加注释 - 若需扩展能力,用嵌套方式组合:
type V2Service interface { UserReader; UserNotifier }
结构体字段:指针 + omitempty 是铁律
v1 客户端不会传新字段,服务端若用值类型接收(如 string Email),反序列化后得到空字符串,可能被误判为有效输入;而用指针(*string)+ omitempty,缺失时字段为 nil,语义清晰且安全。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 新增字段必须是可空类型:
Email *string `json:"email,omitempty"` - 禁止在 v1 结构体上直接加字段——哪怕加了
omitempty,也破坏契约稳定性 - 废弃字段不删,可加
json:"-"阻止输出,但保留在结构体中用于日志或灰度判断
HTTP 路由:/v1/ /v2/ 物理隔离最可靠
用路径前缀做版本路由,不是靠请求头或 query 参数。它天然支持 Nginx 灰度、Prometheus 打点、日志快速归因,也避免中间件漏判导致逻辑错乱。
- 每个版本用独立 router 实例:
v1 := chi.NewRouter()、v2 := chi.NewRouter() - 通过
r.Mount("/v1", v1)和r.Mount("/v2", v2)挂载,不混用中间件 - handler 函数名带版本标识,如
v1GetUserHandler、v2GetUserHandler,杜绝 if 分支判断版本
发布与演进:监控废弃、渐进下线
兼容不是永久背负,而是有节奏地过渡。关键动作要可观察、可度量。
- 废弃字段或接口上线后,加日志统计是否还有客户端传入
- 响应头带上
X-Deprecated: true,配合监控看调用量衰减趋势 - 文档同步更新,明确标注废弃时间、替代方案和下线窗口
- 旧版本 API 至少保留一个主版本周期,给调用方留足迁移时间

















