Some checks failed
Build docker and publish / build (20.15.1) (push) Failing after 7m57s
75 lines
2.0 KiB
Markdown
75 lines
2.0 KiB
Markdown
# API 版本分流接入指南(`api-header`)
|
||
|
||
## 目标
|
||
- 通过请求头 `api-header` 动态选择不同 Handler(如 `001Handler` / `002Handler`)。
|
||
- 让旧 App 无需升级仍可走旧逻辑,新 App 通过版本头走新逻辑。
|
||
|
||
## 当前规则
|
||
- 仅识别请求头:`api-header`
|
||
- 严格版本格式:`x.y.z` 或 `vx.y.z`
|
||
- 仅当 `api-header > 1.0.0` 时走新逻辑(V2)
|
||
- 其余情况(缺失/非法/`<=1.0.0`)走旧逻辑(V1)
|
||
|
||
相关代码:
|
||
- 版本解析:`pkg/apiversion/version.go`
|
||
- 版本注入中间件:`internal/middleware/apiVersionMiddleware.go`
|
||
- 通用分流器:`internal/middleware/apiVersionSwitchHandler.go`
|
||
|
||
## 新接口接入步骤(推荐)
|
||
|
||
### 1) 实现两个 Handler
|
||
```go
|
||
func FooV1Handler(svcCtx *svc.ServiceContext) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
// 旧逻辑(001)
|
||
}
|
||
}
|
||
|
||
func FooV2Handler(svcCtx *svc.ServiceContext) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
// 新逻辑(002)
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2) 在路由中挂分流器
|
||
```go
|
||
group.POST("/foo", middleware.ApiVersionSwitchHandler(
|
||
foo.FooV1Handler(serverCtx),
|
||
foo.FooV2Handler(serverCtx),
|
||
))
|
||
```
|
||
|
||
完成后,无需在业务代码里手写 `api-header` 判断。
|
||
|
||
## 客户端调用示例
|
||
|
||
### 旧逻辑(V1)
|
||
```bash
|
||
curl -X POST 'https://example.com/v1/common/foo' \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"x":1}'
|
||
```
|
||
|
||
### 新逻辑(V2)
|
||
```bash
|
||
curl -X POST 'https://example.com/v1/common/foo' \
|
||
-H 'Content-Type: application/json' \
|
||
-H 'api-header: 1.0.1' \
|
||
-d '{"x":1}'
|
||
```
|
||
|
||
## 测试建议(最小集)
|
||
- 无 `api-header`:命中 V1
|
||
- `api-header: 1.0.0`:命中 V1
|
||
- `api-header: 1.0.1`:命中 V2
|
||
- `api-header: abc`:命中 V1
|
||
|
||
可参考测试:
|
||
- `internal/middleware/apiVersionSwitchHandler_test.go`
|
||
|
||
## 适用建议
|
||
- 差异较小:优先在 V2 中复用现有逻辑,减少重复代码。
|
||
- 差异较大:拆分 V1/V2 各自逻辑,避免分支污染。
|
||
- 上线顺序:先发后端分流能力,再逐步让客户端加 `api-header`。
|