kratos中定义grpc/http双协议接口需满足:proto文件必须置于api/子目录且package名与路径严格一致;必须显式导入google/api/annotations.proto以启用http映射;http路由需通过option(google.api.http)配置,参数须在请求消息中定义;还需导入validate.proto并添加字段校验规则,以及定义带errors.code的errorreason枚举以支持错误码自动映射。

在Kratos项目中定义一个能同时支撑gRPC调用和HTTP网关的接口,必须严格遵循Proto文件的路径、包名、导入和语法规范,否则生成的代码无法注册、HTTP映射失效、甚至编译通过但运行时panic。
Proto文件必须放在api/子目录下
执行kratos proto server或kratos proto client命令时,工具只扫描api/目录及其子目录下的.proto文件。把文件放在proto/、internal/api/或项目根目录下,命令会静默跳过,不报错也不生成任何代码。
正确路径示例:api/greeter/v1/greeter.proto、api/metadata/metadata.proto。
【package名必须与目录结构严格一致】,比如api/greeter/v1/greeter.proto的package必须是kratos.api.greeter.v1,少一级或错拼都会导致生成的Go包路径错误,后续import失败。
必须显式导入google/api/annotations.proto
要启用HTTP映射(如get: "/hello"),必须在proto文件开头import该文件:
import "google/api/annotations.proto";
这个import不是可选的装饰——缺了它,option (google.api.http)整行会被protoc忽略,生成的HTTP路由完全不会存在。Kratos的protoc-gen-go-http插件依赖此import才能注入HTTP绑定逻辑。
注意:该文件需提前安装到$PROTOC_INCLUDE路径下,常见方式是通过go install google.golang.org/api/annotations或从googleapis仓库复制。
服务定义语法与HTTP映射写法
方法1:基础GET映射
在rpc方法后直接添加option块,路径中用{param}占位符提取URL路径参数:
rpc SayHello (HelloRequest) returns (HelloReply) { option (google.api.http) = { get: "/hello/{name}" }; }
此时HelloRequest中必须声明string name = 1;字段,否则运行时HTTP网关解析失败并返回404。
方法2:带查询参数的POST映射
支持将整个请求体映射为JSON POST,同时允许URL中携带额外查询参数:
rpc CreateUser (CreateUserRequest) returns (CreateUserReply) { option (google.api.http) = { post: "/users" body: "*" }; }
这里的body: "*"表示将全部请求体字段作为JSON解析;若指定具体字段如body: "user",则要求CreateUserRequest中存在User user = 1;嵌套消息。
消息字段校验与错误码定义
第一步:启用validate插件支持
在proto文件中import校验规则:import "validate/validate.proto";
第二步:对字段添加约束
例如限制用户名长度:string username = 1 [(validate.rules).string.min_len = 3, (validate.rules).string.max_len = 20];
第三步:定义枚举错误码
在文件末尾添加error定义块,配合errors.proto使用:
enum ErrorReason { option (errors.default_code) = 500; USER_NOT_FOUND = 0 [(errors.code) = 404]; INVALID_INPUT = 1 [(errors.code) = 400]; }
这一步生成的错误码会在HTTP响应头中自动写入X-Error-Code,并在gRPC状态码中映射为对应HTTP状态。











