Snow-kal opened a new issue, #3472:
URL: https://github.com/apache/dubbo-go/issues/3472
# [Feature] 泛化调用优化
## 背景
在 #3167 中,dubbo-go 已经围绕 Java Dubbo 泛化调用补齐了一批核心能力,包括:
- `protobuf-json` 泛化序列化
- `generic.include.class` 配置
- `InvokeWithType` 响应自动反序列化
- `generic=bean` 序列化
- `GenericException` 异常类型保留
目前这些能力已经基本可用,但在实际用于网关、测试平台、跨语言调用时,仍然有一些体验和一致性问题需要继续优化。
这次 issue 希望基于 #3167 继续收敛泛化调用能力,重点提升:
- typed result 行为定义
- generic mode 校验一致性
- 用户侧异常识别和配置 API 清晰度
## 现状
| 功能 | 当前状态 | 需要优化的点 |
|------|----------|--------------|
| Map 泛化调用 (`generic=true`) | 已支持 | typed result 行为需要继续保持稳定 |
| Gson 泛化调用 (`generic=gson`) | 已支持 | typed result / `InvokeWithType`
支持范围需要明确 |
| Protobuf-JSON 泛化调用 (`generic=protobuf-json`) | 已接入 | typed result 行为需要明确 |
| Bean 泛化调用 (`generic=bean`) | 已支持 | 与 `InvokeWithType`、Triple generic
判断的关系需要明确 |
| `InvokeWithType` | 已支持 | 当前只使用 `MapGeneralizer`,无法感知当前 generic mode |
| 普通泛化调用 typed reply | 已支持部分场景 | `OnResponse` 会按 generic mode 取
generalizer,但缺少统一行为定义和测试矩阵 |
| `GenericException` | 已支持 | 类型暴露位置偏底层,用户使用不够方便 |
| `generic.include.class` | 已支持 | 当前通过全局配置读取,用户 API 和文档说明不够清晰 |
| 非法 `generic` 配置 | 当前可能 fallback | 应该尽量早失败并给出明确错误 |
| `protobuf` / `protobuf-json` | 存在兼容差异 | 需要明确 `protobuf` 是否继续作为兼容值保留 |
## 需要补充的功能
### 1. 明确 typed result 与 `InvokeWithType` 的行为边界
目前 `InvokeWithType` 可以把 Map 泛化结果自动反序列化到结构体:
```go
var user User
err := genericService.InvokeWithType(
ctx,
"GetUser",
[]string{"java.lang.String"},
[]hessian.Object{"A003"},
&user,
)
```
但当前实现中,`InvokeWithType` 固定使用 `MapGeneralizer`,主要面向 `generic=true` 的 Map 模式。
同时,普通泛化调用中的 typed reply 路径会在 `OnResponse` 中根据 URL 上的 generic mode 选择
generalizer。这两个路径需要明确区分:
- `InvokeWithType`:需要新增 generic mode 感知能力,或在不支持的 mode 下返回明确错误;
- 普通 typed reply:需要补齐 `true`、`bean`、`gson`、`protobuf-json` 的行为定义和测试覆盖。
另外,当前 `GenericService` 本身不保存 `WithGenericType(...)` 的结果,因此 `InvokeWithType`
无法知道当前是 `bean`、`gson` 还是 `protobuf-json`。需要在实现中明确一种方案:
- 将 generic mode 从 `client.NewGenericService(...)` 传递到
`filter/generic.GenericService`;
- 或定义新的 typed invoke 入口,显式传入 generic mode;
- 或仅声明 `InvokeWithType` 支持 `generic=true`,其他 mode 返回明确错误。
验收效果:
- `generic=true` 下 `InvokeWithType` 保持现有行为;
- `bean`、`gson`、`protobuf-json` 的 typed result 支持情况有明确文档;
- 不支持的 `InvokeWithType` + generic mode 组合返回明确错误,不能 panic 或静默失败;
- 普通 typed reply 的 `OnResponse` 行为有测试矩阵覆盖。
### 2. 提升 `GenericException` 的用户侧可用性
目前 `GenericException` 能保留 Java 异常类名和异常消息,例如:
```go
type GenericException struct {
ExceptionClass string
ExceptionMessage string
}
```
但它现在主要位于较底层的协议包里。业务用户如果想判断 Java 业务异常,需要 import 比较底层的包,不太符合泛化调用的使用直觉。
希望在 `filter/generic` 层提供更友好的入口。建议使用类型别名而不是新增重复类型,例如:
```go
type GenericException = hessian2.GenericException
```
用户侧可以这样使用:
```go
var ge *generic.GenericException
if errors.As(err, &ge) {
fmt.Println(ge.ExceptionClass)
fmt.Println(ge.ExceptionMessage)
}
```
验收效果:
- 用户可以通过 `filter/generic` 包识别泛化异常;
- `errors.As` 能匹配现有底层异常类型;
- Java 业务异常的 class 和 message 不丢失;
- 保持现有底层异常类型兼容。
### 3. 统一 generic mode 校验与兼容策略
当前泛化模式包括:
| 模式 | 参数值 |
|------|--------|
| Map | `true` |
| Gson | `gson` |
| Protobuf-JSON | `protobuf-json` |
| Bean | `bean` |
需要统一校验这些模式,避免传入未知值时静默 fallback 到 Map。
例如:
```go
client.WithGenericType("bad-type")
```
应该在创建引用或调用前返回明确错误,而不是继续执行。
同时需要明确 `protobuf` 的兼容策略。当前部分注释和 Triple 协议判断仍把 `protobuf` 当作合法 generic
值,但本次提案希望收敛到 `protobuf-json`。这里需要明确:
- 如果保留 `protobuf`:应作为兼容值写入文档和校验逻辑;
- 如果不保留 `protobuf`:应拒绝该值,并同步修正注释、测试和 Triple generic 判断。
建议本 issue 采用收敛策略:只接受 `true`、`gson`、`protobuf-json`、`bean`,不再把 `protobuf` 作为新
API 推荐值。
验收效果:
- `client.NewGenericService(..., client.WithGenericType("bad-type"))` 返回明确错误;
- `filter/generic.getGeneralizer` 不再对未知值静默 fallback,或调用方在进入前完成校验;
- Triple generic 判断与 `filter/generic` 使用同一组合法模式;
- `bean` 被 Triple generic 判断识别;
- `protobuf` / `protobuf-json` 的关系在注释和文档中保持一致。
### 4. 优化泛化调用配置入口和文档说明
当前 `client.NewGenericService` 默认使用 Map 泛化方式,并可以通过
`client.WithGenericType(...)` 调整泛化模式。
```go
genericService, err := cli.NewGenericService(
"org.apache.dubbo.samples.UserProvider",
client.WithURL("tri://127.0.0.1:50052"),
client.WithGenericType("bean"),
)
```
但从用户视角看,generic mode、transport serialization、`generic.include.class`
等配置容易混淆。需要补充更清晰的 API 注释和文档说明:
- `generic` 表示泛化格式;
- `serialization` 表示传输序列化方式;
- `generic.include.class` 只影响 Map 泛化中的 `class` 字段;
- `NewGenericService` 默认泛化格式为 `true`;
- `NewGenericService` 默认传输序列化为 Hessian2。
如果本次希望新增用户侧配置入口,需要明确 API,例如:
```go
client.WithGenericIncludeClass(false)
```
如果本次不新增 API,则需要在 issue 中明确:本项仅补充注释和文档,不改变配置入口。
验收效果:
- 用户能清楚区分 generic mode 和 transport serialization;
- `NewGenericService` 的默认行为和可选行为有明确说明;
- `generic.include.class` 的作用范围有明确文档;
- 相关 API 注释与文档保持一致。
## 文件完成情况
| 文件 | 完成情况 | 负责人 |
|------|----------|--------|
| `filter/generic/service.go` | 待处理:补充 `InvokeWithType` generic mode
感知或明确不支持错误 | - |
| `filter/generic/filter.go` | 待处理:明确普通 typed reply 的 `OnResponse` 行为和错误处理 |
- |
| `client/options.go` | 待处理:统一 `WithGenericType` 注释和 generic mode 校验入口 | - |
| `filter/generic/util.go` | 待处理:移除未知 generic mode 静默 fallback,或配合调用方返回明确错误
| - |
| `protocol/triple/triple.go` | 待处理:同步合法 generic mode 集合,补充 `bean`,明确
`protobuf` 策略 | - |
| `filter/generic` | 待处理:通过类型别名暴露 `GenericException` | - |
| `filter/generic/generalizer` | 待处理:补齐 Map / Bean / Gson / Protobuf-JSON
typed result 行为说明和测试 | -|
| `client/client.go` | 待处理:补充 `NewGenericService` 默认 generic mode 和默认
serialization 说明 | - |
| `filter/generic/*_test.go` | 待处理:补充 typed result、非法 generic
mode、`GenericException` 识别测试 | - |
| `protocol/triple/triple_test.go` | 待处理:同步 Triple generic mode 判断测试,覆盖
`bean` 和 `protobuf` 策略 | -|
## 相关文件
dubbo-go 可能需要改动的文件:
| 功能 | 文件 |
|------|------|
| `InvokeWithType` 模式感知 | `filter/generic/service.go` |
| 普通 typed reply 行为 | `filter/generic/filter.go` |
| 泛化模式校验 | `client/options.go` |
| 泛化模式校验 | `filter/generic/util.go` |
| Triple generic mode 判断 | `protocol/triple/triple.go` |
| `GenericException` 用户侧暴露 | `filter/generic` |
| Bean / Map / Gson / Protobuf-JSON typed result |
`filter/generic/generalizer` |
| 配置说明和注释 | `client/client.go` |
| 配置说明和注释 | `client/options.go` |
| 相关测试 | `filter/generic/*_test.go` |
| Triple generic 判断测试 | `protocol/triple/triple_test.go` |
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]