276 lines
7.6 KiB
Markdown
276 lines
7.6 KiB
Markdown
# 目录
|
||
|
||
<!-- vim-markdown-toc GitLab -->
|
||
|
||
* [简介](#简介)
|
||
* [HTTP访问](#http访问)
|
||
* [grpc](#grpc)
|
||
* [安装](#安装)
|
||
* [用法](#用法)
|
||
* [生成结果](#生成结果)
|
||
* [命名规范](#命名规范)
|
||
* [proto包名与版本号](#proto包名与版本号)
|
||
* [生成的go文件的包名](#生成的go文件的包名)
|
||
* [多个proto文件](#多个proto文件)
|
||
* [其他特性](#其他特性)
|
||
* [添加http框架的Middleware](#添加http框架的middleware)
|
||
* [自定义Url或者指定http方法为post](#自定义url或者指定http方法为post)
|
||
* [生成service模板](#生成service模板)
|
||
* [form tag和json tag](#form-tag和json-tag)
|
||
* [指定输入参数的约束条件](#指定输入参数的约束条件)
|
||
* [同步Markdown文档到live-doc仓库(直播Only)](#同步markdown文档到live-doc仓库直播only)
|
||
* [支持json做为输入](#支持json做为输入)
|
||
* [直播部门老的用法](#直播部门老的用法)
|
||
* [兼容直播服务列表(按照discovery id)](#兼容直播服务列表按照discovery-id)
|
||
|
||
<!-- vim-markdown-toc -->
|
||
|
||
## 简介
|
||
根据protobuf文件,生成grpc和blademaster框架http代码及文档
|
||
|
||
|
||
```protobuf
|
||
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
|
||
|
||
## 安装
|
||
|
||
```shell
|
||
go install go-common/app/tool/bmproto/...
|
||
```
|
||
|
||
## 用法
|
||
|
||
- cd 项目目录
|
||
- 在 api目录下新建api.proto文件(参见上面的例子) 例如 api/api.proto
|
||
- 运行 bmgen(在项目的任意位置)
|
||
- 创建 internal/service/greeter.go(这是写业务代码的地方)(也可以通过bmgen -t直接生成)
|
||
|
||
|
||
```go
|
||
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`方法)里加入代码
|
||
|
||
|
||
```go
|
||
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
|
||
|
||
|
||
```protobuf
|
||
.....
|
||
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
|
||
```
|
||
|
||
|
||
### 指定输入参数的约束条件
|
||
|
||
```protobuf
|
||
...
|
||
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 而是 使用注解
|
||
|
||
|
||
```go
|
||
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"
|
||
|
||
|