IDL 与代码生成
IDL 为什么能作为跨语言接口契约?
- IDL: 接口描述语言; 用一份与语言无关的文件定义“有哪些方法、参数长什么样”,然后让工具生成各语言代码;
- 价值: 跨语言、跨团队对齐契约; 代码生成省去手写编解码和桩代码;
如何定义可演进的 Thrift 契约?
- field id: 字段在二进制协议里的身份; 一旦发布,不能修改含义或复用到其他字段;
required: 语义上是“必须携带”; 但新增 required 字段会破坏旧调用方,维护成本高;optional: 未设置时不序列化; 是新增字段最常用的选择;- 默认值: 接收方可能自动构造默认值; 想区分“没传”和“传了零值”时用
optional; - service: 一组方法的集合; 生成代码时会变成接口、Client 和 Server 桩;
namespace go api
struct GetUserRequest {
1: required i64 id
}
struct GetUserResponse {
1: optional string name
}
service UserService {
GetUserResponse GetUser(1: GetUserRequest req)
}
如何从 Thrift IDL 生成 Go 代码?
-module: 生成代码使用的 Go module path; 必须与go.mod一致;-service: 额外生成 Server scaffold; 不指定时只生成类型与 Client 桩;-use: 复用另一个 module 已生成的kitex_gen,避免重复类型;-I: 增加被include的 IDL 搜索目录;- 生成结果:
kitex_gen是派生产物; 不要手工修改,业务写在 Handler;
go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
go install github.com/cloudwego/thriftgo@latest
kitex --version
kitex -module example.com/user -service user api.thrift
如何生成 Protobuf 接口?
- Kitex: 仅支持 proto3;
- 实践:
option go_package必须指向稳定导入路径; - proto: unary 默认使用 Kitex Protobuf(自定义信封,不是标准 gRPC wire);
- IDL: 包含 stream method 时自动切换到 gRPC;
- 实践: 没有 stream 但要求 gRPC 互通时,Client 显式配置
client.WithTransportProtocol(transport.GRPC);