tools/goctl/rpc/README-cn.md
English | 中文
goctl rpc 是 goctl 脚手架下的 RPC 服务代码生成模块,基于 .proto 文件生成完整的 zRPC 服务代码。你只需编写 proto 定义和业务逻辑,其余代码均由工具自动生成。
google.protobuf.* 类型并生成正确的 Go 导入# 安装 protoc 插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
goctl rpc new greeter
生成完整的项目结构:
greeter/
├── etc/
│ └── greeter.yaml
├── greeter/
│ ├── greeter.pb.go
│ └── greeter_grpc.pb.go
├── greeter.go
├── greeter.proto
├── greeterclient/
│ └── greeter.go
└── internal/
├── config/
│ └── config.go
├── logic/
│ └── pinglogic.go
├── server/
│ └── greeterserver.go
└── svc/
└── servicecontext.go
goctl rpc template -o=user.proto
mkdir -p output && cd output && go mod init example.com/demo && cd ..
goctl rpc protoc user.proto \
--go_out=output --go-grpc_out=output --zrpc_out=output \
--go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
--module=example.com/demo -I .
goctl rpc protoc从 .proto 文件生成 zRPC 服务代码。
goctl rpc protoc <proto_file> [flags]
示例:
# 基础用法
goctl rpc protoc user.proto \
--go_out=output --go-grpc_out=output --zrpc_out=output \
--go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
--module=example.com/demo -I .
# 多服务模式
goctl rpc protoc multi.proto \
--go_out=output --go-grpc_out=output --zrpc_out=output \
--go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
--module=example.com/demo -I . -m
# 导入外部 proto
goctl rpc protoc service.proto \
--go_out=output --go-grpc_out=output --zrpc_out=output \
--go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
--module=example.com/demo -I . -I ./shared_protos
# 使用 Google 标准类型
goctl rpc protoc service.proto \
--go_out=output --go-grpc_out=output --zrpc_out=output \
--go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
--module=example.com/demo -I .
参数说明:
| 参数 | 缩写 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
--zrpc_out | string | 必填 | zRPC 服务代码输出目录 | |
--go_out | string | 必填 | protoc Go 代码输出目录 | |
--go-grpc_out | string | 必填 | protoc gRPC 代码输出目录 | |
--go_opt | string | protoc-gen-go 选项(如 module=example.com/demo) | ||
--go-grpc_opt | string | protoc-gen-go-grpc 选项(如 module=example.com/demo) | ||
--proto_path | -I | string[] | proto 导入搜索目录(可多次指定) | |
--multiple | -m | bool | false | 多服务模式 |
--client | -c | bool | true | 是否生成 RPC 客户端代码 |
--style | string | gozero | 文件命名风格 | |
--module | string | 自定义 Go module 名称 | ||
--name-from-filename | bool | false | 使用文件名而非 package 名命名服务 | |
--verbose | -v | bool | false | 显示详细日志 |
--home | string | goctl 模板目录 | ||
--remote | string | 远程模板 Git 仓库地址 | ||
--branch | string | 远程模板分支 |
goctl rpc new快速创建一个完整的 RPC 服务项目。
goctl rpc new <service_name> [flags]
参数说明:
| 参数 | 缩写 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
--style | string | gozero | 文件命名风格 | |
--client | -c | bool | true | 是否生成 RPC 客户端代码 |
--module | string | 自定义 Go module 名称 | ||
--verbose | -v | bool | false | 显示详细日志 |
--idea | bool | false | 生成 IDE 项目标记 | |
--name-from-filename | bool | false | 使用文件名而非 package 名命名服务 | |
--home | string | goctl 模板目录 | ||
--remote | string | 远程模板 Git 仓库地址 | ||
--branch | string | 远程模板分支 |
goctl rpc template生成 proto 文件模板。
goctl rpc template -o=<output_file> [flags]
参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
-o | string | 输出文件路径(必填) |
--home | string | goctl 模板目录 |
--remote | string | 远程模板 Git 仓库地址 |
--branch | string | 远程模板分支 |
--multiple)当 proto 文件包含多个 service 定义时,必须使用 --multiple 标志。
service SearchService {
rpc Search(SearchReq) returns (SearchReply);
}
service NotifyService {
rpc Notify(NotifyReq) returns (NotifyReply);
}
启用 --multiple 后的目录变化:
| 特性 | 默认模式 | --multiple 模式 |
|---|---|---|
| 服务数量 | 仅 1 个 | 1 个或多个 |
| 客户端目录 | 以服务名命名 | 固定为 client/ |
| 代码组织 | 扁平结构 | 按服务名分组 |
--multiple=false(默认)的目录结构:
output/
├── greeterclient/
│ └── greeter.go
├── internal/
│ ├── logic/
│ │ └── sayhellologic.go
│ └── server/
│ └── greeterserver.go
└── ...
--multiple=true 的目录结构:
output/
├── client/
│ ├── searchservice/
│ │ └── searchservice.go
│ └── notifyservice/
│ └── notifyservice.go
├── internal/
│ ├── logic/
│ │ ├── searchservice/
│ │ │ └── searchlogic.go
│ │ └── notifyservice/
│ │ └── notifylogic.go
│ └── server/
│ ├── searchservice/
│ │ └── searchserviceserver.go
│ └── notifyservice/
│ └── notifyserviceserver.go
└── ...
--proto_path)通过 -I / --proto_path 指定额外的 proto 搜索目录,支持以下场景:
import "types.proto";import "common/types.proto";go_package 的 proto 文件,自动生成正确的 Go 导入# 从多个目录搜索 proto 文件
goctl rpc protoc service.proto \
--go_out=output --go-grpc_out=output --zrpc_out=output \
--go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
--module=example.com/demo \
-I . -I ./shared_protos -I /path/to/external_protos
默认情况下,服务名称来自 proto 的 package 名称(例如 package user; → 服务名 user)。这使得多个 proto 文件可以共享同一个 package:
protos/
├── user_base.proto # package user;
├── user_auth.proto # package user;
└── user_profile.proto # package user;
三个文件会生成到同一个 user 服务中。
如需使用 proto 文件名命名(旧版行为),请添加 --name-from-filename 标志。
支持 gRPC 的三种流式模式:
service StreamService {
rpc ServerStream(Req) returns (stream Reply); // 服务端流
rpc ClientStream(stream Req) returns (Reply); // 客户端流
rpc BidiStream(stream Req) returns (stream Reply); // 双向流
}
goctl 自动识别并正确处理 Google protobuf 标准类型:
| Proto 类型 | Go 类型 |
|---|---|
google.protobuf.Empty | emptypb.Empty |
google.protobuf.Timestamp | timestamppb.Timestamp |
google.protobuf.Duration | durationpb.Duration |
google.protobuf.Any | anypb.Any |
google.protobuf.Struct | structpb.Struct |
google.protobuf.FieldMask | fieldmaskpb.FieldMask |
google.protobuf.*Value | wrapperspb.*Value |
这些类型可直接用作 RPC 参数类型,goctl 会自动生成正确的导入。
详见 example/ 目录,包含 10 个完整示例,覆盖所有生成场景。
| # | 示例 | 场景 |
|---|---|---|
| 01 | 基础服务 | 单服务,无导入 |
| 02 | 同级导入 | 导入同目录 proto |
| 03 | 子目录导入 | 导入子目录 proto |
| 04 | 传递性导入 | A → B → C 依赖链 |
| 05 | 多服务 | --multiple 模式 |
| 06 | 标准类型 | 消息中使用 Timestamp 等 |
| 07 | 外部 Proto(同包) | 外部 proto,相同 go_package |
| 08 | 外部 Proto(跨包) | 外部 proto,不同 go_package |
| 09 | 标准类型作参数 | Empty/Timestamp 作为 RPC 参数 |
| 10 | 流式通信 | 服务端/客户端/双向流 |