这里主要进行修订 Proto 规范约定和多语言之间特定商定,帮助大家写出更标准的接口。
API 接口统一以 HTTP/GRPC 为基础,并通过 Protobuf 进行协议定义,包括完整的 Request/Reply,以及对应的接口错误码(Errors)。
API 接口可以定义到项目,或者在统一仓库中管理 Proto,类似 googleapis
、envoy-api
、istio-api
;
项目中定义 Proto,以 api 为包名根目录:
kratos-demo:|____api // 服务API定义| |____kratos| | |____demo| | | |____v1| | | | |____demo.proto
在统一仓库中管理 Proto,以仓库为包名根目录:
kratos-apis:|____api // 服务API定义| |____kratos| | |____demo| | | |____v1| | | | |____demo.proto|____annotations // 注解定义options|____third_party // 第三方引用
包名为应用的标识(APP_ID),用于生成 gRPC 请求路径,或者 Proto 之间进行引用 Message。
my.package.v1
,为 API 目录,定义 service 相关接口,用于提供业务使用。例如:
// RequestURL: /<package_name>.<version>.<service_name>/{method}package <package_name>.<version>;
option go_package = "github.com/go-kratos/kratos/<package_name>;<version>";
option java_multiple_files = true;option java_package = "com.github.kratos.<package_name>.<version>";
option objc_class_prefix = "<PackageNameVersion>";
该版本号为标注不兼容版本,并且会在 <package_name>
中进行区分,当接口需要重构时一般会更新不兼容结构。
protobuf
、google rpc
、google apis
、gogo
定义。包名为小写,并且同目录结构一致,例如:my/package/v1/
。
package my.package.v1;
文件应该命名为:lower_snake_case.proto
。
所有 Proto 应按下列方式排列:
使用驼峰命名法(首字母大写)命名 message,例子:SongServerRequest
。
使用下划线命名字段,例子:song_name
。
Proto2 和 Proto3 的语法也有所不同。
message SongServerRequest { optional string song_name = 1;}
使用上述这种字段的命名约定,生成的访问器将类似于如下代码:
C++: const string& song_name() { ... } void set_song_name(const string& x) { ... }
Java: public String getSongName() { ... } public Builder setSongName(String v) { ... }
如果你的字段名包含一个数字,数字应该出现在字母后面,而不是下划线后面。例如,使用 song_name1
而不是 song_name_1
。
对于复数命名的 message 使用 repeated 字段。
repeated string keys = 1;...repeated Account accounts = 17;
枚举类型使用驼峰命名法(首字母大写)命名,使用 CAPITALS_WITH_UNDERSCORES(带下划线的大写字母)
的方式命名枚举值:
enum FooBar { FOO_BAR_UNSPECIFIED = 0; FOO_BAR_FIRST_VALUE = 1; FOO_BAR_SECOND_VALUE = 2;}
每一个枚举值以分号结尾,而非逗号。倾向于给枚举值加前缀,而不是用一个包围的信息包围它们。零值枚举应该有后缀 UNSPECIFIED
。
如果你在 .proto
文件中定义 RPC 服务,你应该使用驼峰命名法(首字母大写)命名 RPC 服务以及其中的 RPC 方法:
service FooService { rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse); rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse);}
API Service 接口定义(demo.proto)
syntax = "proto3";
package kratos.demo.v1;
// 多语言特定包名,用于源代码引用option go_package = "github.com/go-kratos/kratos/demo/v1;v1"; // ';' 后面的 <version> 是为了生成对应代码option java_multiple_files = true;option java_package = "com.github.kratos.demo.v1";option objc_class_prefix = "KratosDemoV1";
// 描述该服务的信息service Greeter { // 描述该方法的功能 rpc SayHello (HelloRequest) returns (HelloReply);}// Hello请求参数message HelloRequest { // 用户名字 string name = 1;}// Hello返回结果message HelloReply { // 结果信息 string message = 1;}