准备
基于proto
文件可以快速生成bm
框架对应的代码,提前需要准备以下工作:
- 安装Protobuf(第一节已进行过详细介绍,如果已安装可跳过),CentOS安装,Windows安装
- 熟悉protobuf协议,请看Protobuf3语言指南
- 安装
kratos tool protoc
工具,请看kratos工具 - 编写
proto
文件,示例可参考kratos-demo内proto文件
创建新项目
kratos new pbdemo --http
查看项目文件pbdemo/api/api.proto
:
// 定义项目 API 的 proto 文件 可以同时描述 gRPC 和 HTTP API
// protobuf 文件参考:
// - https://developers.google.com/protocol-buffers/
syntax = "proto3";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "google/protobuf/empty.proto";
import "google/api/annotations.proto";
// package 命名使用 {appid}.{version} 的方式, version 形如 v1, v2 ..
package demo.service.v1;
option go_package = "api";
option (gogoproto.goproto_getters_all) = false;
//定义服务接口
service Demo {
rpc Ping(.google.protobuf.Empty) returns (.google.protobuf.Empty);
rpc SayHello(HelloReq) returns (.google.protobuf.Empty);
rpc SayHelloURL(HelloReq) returns (HelloResp) {
option (google.api.http) = {
get: "/demo/say_hello"
};
};
}
//定义请求参数
message HelloReq {
string name = 1 [(gogoproto.moretags) = 'form:"name" validate:"required"'];
}
//定义响应参数
message HelloResp {
string Content = 1 [(gogoproto.jsontag) = 'content'];
}
运行项目:
kratos run
打开浏览器访问:
http://localhost:8000/demo/say_hello?name=Soul
输出内容:
{
"code": 0,
"message": "0",
"ttl": 1,
"data": {
"content": "hello Soul"
}
}
kratos工具说明
kratos tool protoc
工具可以生成warden
bm
swagger
对应的代码和文档,想要单独生成bm
代码只需加上--bm
如:
# generate BM HTTP
kratos tool protoc --bm api.proto
proto文件说明
请注意想要生成bm
代码,需要特别在proto
的service
内指定google.api.http
配置,如下:
service Demo {
rpc SayHello (HelloReq) returns (.google.protobuf.Empty);
rpc SayHelloURL(HelloReq) returns (HelloResp) {
option (google.api.http) = { // 该配置指定SayHelloURL方法对应的url
get:"/demo/say_hello" // 指定url和请求方式为GET
};
};
}
使用
建议在项目api
目录下编写proto
文件及生成对应的代码,可参考pbdemo
内的api
目录。
执行命令后生成的api.bm.go
代码,注意其中的type DemoBMServer interface
和RegisterDemoBMServer
:
DemoBMServer
接口,包含proto文件内配置了google.api.http
选项的所有方法RegisterDemoBMServer
方法提供注册DemoBMServer
接口的实现对象,和bm
的Engine
用于注册路由DemoBMServer
接口的实现,一般为internal/service
内的业务逻辑代码,需要实现DemoBMServer
接口
internal/server/http/server.go
使用RegisterDemoBMServer
示例代码:
engine = bm.DefaultServer(hc.Server)
pb.RegisterDemoBMServer(engine, svc)
initRouter(engine)
internal/service/service.go
内的Service结构实现了DemoBMServer
接口代码:
// SayHelloURL bm demo func.
func (s *Service) SayHelloURL(ctx context.Context, req *pb.HelloReq) (reply *pb.HelloResp, err error) {
reply = &pb.HelloResp{
Content: "hello " + req.Name,
}
fmt.Printf("hello url %s", req.Name)
return
}
新增自定义接口
修改pbdemo/api/api.proto
文件内容:
// 定义项目 API 的 proto 文件 可以同时描述 gRPC 和 HTTP API
// protobuf 文件参考:
// - https://developers.google.com/protocol-buffers/
syntax = "proto3";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "google/protobuf/empty.proto";
import "google/api/annotations.proto";
// package 命名使用 {appid}.{version} 的方式, version 形如 v1, v2 ..
package demo.service.v1;
option go_package = "api";
option (gogoproto.goproto_getters_all) = false;
//定义服务接口
service Demo {
rpc Ping(.google.protobuf.Empty) returns (.google.protobuf.Empty);
rpc SayHello(HelloReq) returns (.google.protobuf.Empty);
rpc SayHelloURL(HelloReq) returns (HelloResp) {
option (google.api.http) = {
get: "/demo/say_hello"
};
};
//新增登录服务接口
rpc Login(LoginReq) returns (LoginResp) {
option (google.api.http) = {
get: "/user/login"
};
};
}
message HelloReq {
string name = 1 [(gogoproto.moretags) = 'form:"name" validate:"required"']; //form-表单name
}
message HelloResp {
string Content = 1 [(gogoproto.jsontag) = 'content'];
}
//新增登录接口请求参数
message LoginReq {
string username = 1 [(gogoproto.moretags) = 'form:"username" validate:"required"']; //form-表单username
string passwd = 2 [(gogoproto.moretags) = 'form:"passwd" validate:"required"']; //form-表单passwd
}
//新增登录接口响应参数
message LoginResp {
string Content = 1 [(gogoproto.jsontag) = 'content'];
}
internal/service/service.go
新增以下内容:
//新增登录接口
func (s *Service) Login(ctx context.Context, req *pb.LoginReq) (reply *pb.LoginResp, err error) {
reply = &pb.LoginResp{
Content: "login:" + req.Username + ", passwd: "+req.Passwd,
}
fmt.Printf("login url %s", req.Username)
return
}
生成文件:
cd pbdemo/api
kratos tool protoc api.proto #生成的pb.go文件
cd pbdemo/internal/di
go generate #生成新的go接口, 貌似不用执行这个也行, 可以自行尝试一下
运行项目:
kratos run
打开浏览器访问:
http://localhost:8000/user/login?username=Soul&passwd=111111
输出内容:
{
"code": 0,
"message": "0",
"ttl": 1,
"data": {
"content": "login:Soul, passwd: 111111"
}
}
文档
基于同一份proto
文件还可以生成对应的swagger
文档,运行命令如下:
# generate swagger
kratos tool protoc --swagger api.proto
该命令将生成对应的swagger.json
文件,可用于swagger
工具通过WEBUI的方式打开使用,可运行命令如下:
kratos tool swagger serve api/api.swagger.json