@ -8,74 +8,118 @@ Goctl Rpc是`goctl`脚手架下的一个rpc服务代码生成模块, 支持prot
# 快速开始
### 生成proto模板
### 方式一: 快速生成greet服务
```shell script
$ goctl rpc template -o=user.proto
```
通过命令 `goctl rpc new ${servieName}` 生成
```golang
syntax = "proto3";
package remote;
message Request {
// 用户名
string username = 1;
// 用户密码
string password = 2;
}
message Response {
// 用户名称
string name = 1;
// 用户性别
string gender = 2;
}
service User {
// 登录
rpc Login(Request)returns(Response);
}
```
### 生成rpc服务代码
如生成greet rpc服务:
生成user rpc服务
```
$ goctl rpc proto -src=user.proto
```
```shell script
$ goctl rpc new greet
```
代码tree
执行后代码结构如下:
```
user
```golang
└── greet
├── etc
│ └── user.json
│ └── greet.yaml
├── go.mod
├── go.sum
├── greet
│ ├── greet.go
│ ├── greet_mock.go
│ └── types.go
├── greet.go
├── greet.proto
├── internal
│ ├── config
│ │ └── config.go
│ ├── handler
│ │ ├── loginhandler.go
│ ├── logic
│ │ └── loginlogic.go
│ │ └── pinglogic.go
│ ├── server
│ │ └── greetserver.go
│ └── svc
│ └── servicecontext.go
├── pb
│ └── user.pb.go
├── shared
│ ├── mockusermodel.go
│ ├── types.go
│ └── usermodel.go
├── user.go
└── user.proto
```
└── pb
└── greet.pb.go
```
rpc一键生成常见问题解决见 < a href = "#常见问题解决" > 常见问题解决< / a >
### 方式二: 通过指定proto生成rpc服务
* 生成proto模板
```shell script
$ goctl rpc template -o=user.proto
```
```golang
syntax = "proto3";
package remote;
message Request {
// 用户名
string username = 1;
// 用户密码
string password = 2;
}
message Response {
// 用户名称
string name = 1;
// 用户性别
string gender = 2;
}
service User {
// 登录
rpc Login(Request)returns(Response);
}
```
* 生成rpc服务代码
```
$ goctl rpc proto -src=user.proto
```
代码tree
```
user
├── etc
│ └── user.json
├── internal
│ ├── config
│ │ └── config.go
│ ├── handler
│ │ ├── loginhandler.go
│ ├── logic
│ │ └── loginlogic.go
│ └── svc
│ └── servicecontext.go
├── pb
│ └── user.pb.go
├── shared
│ ├── mockusermodel.go
│ ├── types.go
│ └── usermodel.go
├── user.go
└── user.proto
```
# 准备工作
* 安装了go环境
* 安装了protoc& protoc-gen-go, 并且已经设置环境变量
* mockgen(可选)
* mockgen(可选,将移除)
* 更多问题请见 < a href = "#注意事项" > 注意事项< / a >
# 用法
### rpc服务生成用法
```shell script
$ goctl rpc proto -h
```
@ -91,27 +135,28 @@ OPTIONS:
--src value, -s value the file path of the proto source file
--dir value, -d value the target path of the code,default path is "${pwd}". [option]
--service value, --srv value the name of rpc service. [option]
--shared value the dir of the shared file,default path is "${pwd}/shared. [option]"
--shared[已废弃] value the dir of the shared file,default path is "${pwd}/shared. [option]"
--idea whether the command execution environment is from idea plugin. [option]
```
* 参数说明
* --src 必填, proto数据源, 目前暂时支持单个proto文件生成, 这里不支持( 不建议) 外部依赖
* --dir 非必填, 默认为proto文件所在目录, 生成代码的目标目录
* --service 服务名称, 非必填, 默认为proto文件所在目录名称, 但是, 如果proto所在目录为一下结构:
```shell script
user
├── cmd
│ └── rpc
│ └── user.proto
```
则服务名称亦为user, 而非proto所在文件夹名称了, 这里推荐使用这种结构, 可以方便在同一个服务名下建立不同类型的服务(api、rpc、mq等),便于代码管理与维护。
* --shared 非必填,默认为$dir(xxx.proto)/shared, rpc client逻辑代码存放目录。
> 注意: 这里的shared文件夹名称将会是代码中的package名称。
* --idea 非必填, 是否为idea插件中执行, 保留字段, 终端执行可以忽略
### 参数说明
* --src 必填, proto数据源, 目前暂时支持单个proto文件生成, 这里不支持( 不建议) 外部依赖
* --dir 非必填, 默认为proto文件所在目录, 生成代码的目标目录
* --service 服务名称, 非必填, 默认为proto文件所在目录名称, 但是, 如果proto所在目录为一下结构:
```shell script
user
├── cmd
│ └── rpc
│ └── user.proto
```
则服务名称亦为user, 而非proto所在文件夹名称了, 这里推荐使用这种结构, 可以方便在同一个服务名下建立不同类型的服务(api、rpc、mq等),便于代码管理与维护。
* --shared[⚠️已废弃] 非必填,默认为$dir(xxx.proto)/shared, rpc client逻辑代码存放目录。
> 注意: 这里的shared文件夹名称将会是代码中的package名称。
* --idea 非必填, 是否为idea插件中执行, 保留字段, 终端执行可以忽略
# 开发人员需要做什么
@ -124,6 +169,10 @@ OPTIONS:
对于需要进行rpc mock的开发人员, 在安装了`mockgen`工具的前提下可以在rpc的shared文件中生成好对应的mock文件。
# 注意事项
* `google.golang.org/grpc` 需要降级到v1.26.0,且protoc-gen-go版本不能高于v1.3.2( see [https://github.com/grpc/grpc-go/issues/3347 ](https://github.com/grpc/grpc-go/issues/3347 ))即
```
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
```
* proto不支持暂多文件同时生成
* proto不支持外部依赖包引入, message不支持inline
* 目前main文件、shared文件、handler文件会被强制覆盖, 而和开发人员手动需要编写的则不会覆盖生成, 这一类在代码头部均有
@ -133,8 +182,42 @@ OPTIONS:
```
的标识,请注意不要将也写业务性代码写在里面。
# 常见问题解决(go mod工程)
* 错误一:
```golang
pb/xx.pb.go:220:7: undefined: grpc.ClientConnInterface
pb/xx.pb.go:224:11: undefined: grpc.SupportPackageIsVersion6
pb/xx.pb.go:234:5: undefined: grpc.ClientConnInterface
pb/xx.pb.go:237:24: undefined: grpc.ClientConnInterface
```
解决方法:请将`protoc-gen-go`版本降至v1.3.2及一下
* 错误二:
```golang
# go.etcd.io/etcd/clientv3/balancer/picker
../../../go/pkg/mod/go.etcd.io/etcd@v0.0.0-20200402134248-51bdeb39e698/clientv3/balancer/picker/err.go:25:9: cannot use & errPicker literal (type *errPicker) as type Picker in return argument:*errPicker does not implement Picker (wrong type for Pick method)
have Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error)
want Pick(balancer.PickInfo) (balancer.PickResult, error)
../../../go/pkg/mod/go.etcd.io/etcd@v0.0.0-20200402134248-51bdeb39e698/clientv3/balancer/picker/roundrobin_balanced.go:33:9: cannot use & rrBalanced literal (type *rrBalanced) as type Picker in return argument:
*rrBalanced does not implement Picker (wrong type for Pick method)
have Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error)
want Pick(balancer.PickInfo) (balancer.PickResult, error)
#github .com/tal-tech/go-zero/rpcx/internal/balancer/p2c
../../../go/pkg/mod/github.com/tal-tech/go-zero@v1.0.12/rpcx/internal/balancer/p2c/p2c.go:41:32: not enough arguments in call to base.NewBalancerBuilder
have (string, *p2cPickerBuilder)
want (string, base.PickerBuilder, base.Config)
../../../go/pkg/mod/github.com/tal-tech/go-zero@v1.0.12/rpcx/internal/balancer/p2c/p2c.go:58:9: cannot use & p2cPicker literal (type *p2cPicker) as type balancer.Picker in return argument:
*p2cPicker does not implement balancer.Picker (wrong type for Pick method)
have Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error)
want Pick(balancer.PickInfo) (balancer.PickResult, error)
```
解决方法:
```golang
replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
```