7.6 KiB
7.6 KiB
目录
简介
根据protobuf文件,生成grpc和blademaster框架http代码及文档
syntax = "proto3";
package department.app;
option go_package = "api";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
service Greeter{
// api 标题
// api 说明
rpc SayHello(HelloRequest) returns (HelloResponse);
}
message HelloRequest {
// 请求参数说明
string param1 = 1 [(gogoproto.moretags) = 'form:"param1"'];
}
message HelloResponse {
// 返回字段说明
string ret_string = 1 [(gogoproto.jsontag) = 'ret_string'];
}
HTTP访问
GET /department.app.Greeter/SayHello?param1=p1
响应
{
"code": 0,
"message": "ok",
"data": {
"ret_string": "anything"
}
}
grpc
路径 /department.app.Greeter/SayHello
安装
go install go-common/app/tool/bmproto/...
用法
- cd 项目目录
- 在 api目录下新建api.proto文件(参见上面的例子) 例如 api/api.proto
- 运行 bmgen(在项目的任意位置)
- 创建 internal/service/greeter.go(这是写业务代码的地方)(也可以通过bmgen -t直接生成)
import pb "path-to-project/api"
....
// 实现 pb.GreeterBMServer 和 grpc的 pb.GreeterServer
type GreeterService struct {
}
func (s *GreeterService) SayHello(ctx context.Context, req *pb.SayHelloRequest)
(resp *pb.SayHelloResp, err error) {
}
- 在server/http.go 初始化代码(一般是
route
方法)里加入代码
import pb "path-to-project/api"
import svc "path-to-project/internal/service"
......
pb.RegisterGreeterBMServer(engine, &svc.GreeterService{})
- 如果是grpc 在server/grpc/server.go 初始化里面加入代码
pb.RegisterGreeterServer(grpcServer, &svc.GreeterService{})
- 启动服务
- 访问接口
curl 127.0.0.1:8000/department.app.Greeter/SayHello
(默认路由规则为/package.service/method
)
生成结果
project-
|------|--internal/service/greeter.go (使用bmgen -t 会生成,如果proto新增加方法,会自动往这里面添加模板代码)
|--api/
|--api.greeter.md (HTTP API文档)
|--api.bm.go
|--api.pb.go
|--api.proto
命名规范
proto包名与版本号
- DISCOVERY_ID 或者 DISCOVERY_ID.v*
- DISCOVERY_ID的构成为
部门.服务
并且去掉中划线 - 第一个版本不用加版本号,从第二个版本加v2
- 示例 部门 department 服务 hello-world, 则 package为
department.helloworld
, 文件目录为api/ - 第二个版本package `department.helloworld.v2", 目录为api/v2
生成的go文件的包名
- golang一般原则上保持包名和目录名一致
- proto 可以指定
option go_package = "xxx";
比如对于api/api.proto option go_package = "api";
对于api/v2/api.proto option go_package = "v2";
多个proto文件
一个文件夹下面可以有多个proto文件,但是要满足以下约束
- 同目录下的proto package 一致
- message service 等定义不能重复(因为是在统一package下面)
其他特性
添加http框架的Middleware
在RegisterXXBMServer之前加入代码
bm.Inject(pb.PathGreeterSayHello, middleware1, middleware2)
自定义Url或者指定http方法为post
.....
package department.app;
....
import "google/api/annotations.proto";
....
service Greeter{
rpc SayHelloCustomUrl(HelloRequest) returns (HelloResponse) {
option (google.api.http) = {
get:"/say_hello" // GET /say_hello
};
};
rpc SayHelloPost(HelloRequest) returns (HelloResponse) {
option (google.api.http) = {
post:"" // POST /department.app.Greeter/SayHelloPost
};
};
}
生成service模板
bmgen -t
生成service模板代码在 internal/service/serviceName.go
form tag和json tag
对于HTTP接口
现在请求字段需要加上form tag以解析请求参数,
响应参数需要加上json tag 以避免 字段为0或者空字符串时不显示,
这两个tag都建议和字段名保持一致
现在是必须加,将来考虑维护一个自己的proto仓库,以移除这个多余的tag
指定输入参数的约束条件
...
import "github.com/gogo/protobuf/gogoproto/gogo.proto"
...
message Request {
int param1 = 1 [(gogoproto.moretags) = 'validate:"required"')]; // 参数必传,不能等于0
}
同步Markdown文档到live-doc仓库(直播Only)
bmgen -l
支持json做为输入
curl 127.0.0.1:8000/department.app.Greeter/SayHello -H "Content-Type: application/json" -d "{"param1":"p1"}" -X POST
直播部门老的用法
对于以下"兼容直播服务列表中的服务"有效
- URL:/xlive/项目名/v*/service开头小写/method
- 注册路由:使用RegisterXXXService而不是 RegisterXXBMServer
- middleware:不支持RegisterXXXMiddleware 而是 使用注解
api/api.proto
service Greeter {
// `method:"POST"` // 表示请求方法为POST
// `midware:"user"`
rpc SayHello(A) returns (B);
}
// server/http/http.go
import bm "go-common/library/net/http/blademaster"
....
userAuthMiddleware := xxxxx
pb.RegisterXXService(e, svc, map[string]bm.HandlerFunc{"user":userAuthMiddleware})
-
注解,在方法或者字段上方的注视添加和 go的tag格式一样的注解,实现一定的功能
注解列表:
key 位置 说明 midware rpc method上方 midware:"auth,verify" 中间件,auth 是验证登录态,verify是校验签名, method rpc method上方 method:"POST" 指定http请求方法 mock 响应message的字段上方 mock:"mockdata" mock数据,生成文档的时候有用 internal 不建议继续使用 不建议继续使用 dynamic 不建议继续使用 不建议继续使用 dynamic_resp 不建议继续使用 不建议继续使用
兼容直播服务列表(按照discovery id)
- "live.webucenter"
- "live.webroom"
- "live.appucenter"
- "live.appblink"
- "live.approom"
- "live.appinterface"
- "live.liveadmin"
- "live.resource"
- "live.livedemo"
- "live.lotteryinterface"