协议文件指的是*.proto
文件,proto
是gRPC
协议通讯的标准,可以类比为json
和HTTP
。但是千万不要理解proto
就是json
,他们还是有一定区别的:proto
同时定义“接口”信息和响应参数,请求参数,而json
就单纯的保存数据。
proto
文件统一存放在manifest/protobuf
下,和普通的HTTP
服务一样,使用目录层级来管理接口版本。
用户注册
创建一个名为account
的目录,管理用户账号相关业务。
app/user/manifest/protobuf/account/v1/account.proto
syntax = "proto3";
package account.v1;
option go_package = "proxima/app/user/api/account/v1";
service Account{
rpc UserRegister(UserRegisterReq) returns (UserRegisterRes) {}
}
message UserRegisterReq {
string username = 1; // v:required|min-length:2
string password = 2; // v:required|min-length:6
string email = 3; // v:required|email
}
message UserRegisterRes {
int32 id = 1;
}
简单的介绍一下proto
语法:
- syntax 规定本文件语法版本;
- package 定义的是服务命名空间,可以理解为包名;
- option 设定编译选项,
go_package
指定生成的Go
代码所属的包名。在GoFrame
中固定格式是项目名 + app + 微服务名称 + api + 模块名 + v1
; - service 定义远程调用方法,一般是
RPC
,规定其请求和响应参数; - message 定义数据结构,
string
是数据类型,username
是字段名,赋值号后面的递增数字是字段编号。最后面的注释是框架提供的参数校检,使用方式普通的HTTP
接口一致。
我们的文件定义了以下内容:
- 使用
proto3
语法版本的定义; - 定义了包名为
account.v1
; - 设置了
Go
代码生成的包路径选项go_package
为proxima/app/user/api/account/v1
; - 定义了一个
Account
服务,包含一个RPC
方法UserRegister
,它接受UserRegisterReq
消息并返回UserRegisterRes
消息; - 定义了一个消息类型
UserRegisterReq
,包含三个字段:username
(字符串类型,编号为1)password
(字符串类型,编号为2)email
(字符串类型,编号为3)
- 定义了一个消息类型
UserRegisterRes
,包含一个字段:id
(整型,编号为1)
用户登录/查询
照葫芦画瓢,我们继续定义用户登录和查询接口。最后的文件内容如下:
app/user/manifest/protobuf/account/v1/account.proto
syntax = "proto3";
package account.v1;
option go_package = "proxima/app/user/api/account/v1";
import "pbentity/users.proto";
service Account{
rpc UserRegister(UserRegisterReq) returns (UserRegisterRes) {}
rpc UserLogin(UserLoginReq) returns (UserLoginRes) {}
rpc UserInfo(UserInfoReq) returns (UserInfoRes) {}
}
message UserRegisterReq {
string username = 1; // v:required|min-length:2
string password = 2; // v:required|min-length:6
string email = 3; // v:required|email
}
message UserRegisterRes {
int32 id = 1;
}
message UserLoginReq {
string username = 1; // v:required|min-length:2
string password = 2; // v:required|min-length:6
}
message UserLoginRes {
string token = 1;
}
message UserInfoReq {
string token = 1; // v:required
}
message UserInfoRes {
pbentity.Users user = 1;
}
这里多了两个新的语法:
import "pbentity/users.proto";
,代表引入了其他proto
文件。引入的这个文件是gf gen pbentity
生成的;pbentity.Users user
调用引入的数据模型,和go
的结构体几乎一致。