tools/goctl/rpc/README.md
English | 中文
goctl rpc is the RPC service code generation module of the goctl scaffold. It generates a complete zRPC service from .proto files. You only need to write the proto definition and business logic — all boilerplate code is generated automatically.
google.protobuf.* types with correct Go imports# Install protoc plugins
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
Generates a complete project structure:
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 protocGenerate zRPC service code from a .proto file.
goctl rpc protoc <proto_file> [flags]
Examples:
# Basic usage
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 .
# Multiple services mode
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
# Import external protos
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
# Use Google well-known types
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 .
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--zrpc_out | string | required | Output directory for zRPC service code | |
--go_out | string | required | Output directory for protoc Go code | |
--go-grpc_out | string | required | Output directory for protoc gRPC code | |
--go_opt | string | Options for protoc-gen-go (e.g., module=example.com/demo) | ||
--go-grpc_opt | string | Options for protoc-gen-go-grpc (e.g., module=example.com/demo) | ||
--proto_path | -I | string[] | Proto import search directories (repeatable) | |
--multiple | -m | bool | false | Multiple services mode |
--client | -c | bool | true | Generate RPC client code |
--style | string | gozero | File naming style | |
--module | string | Custom Go module name | ||
--name-from-filename | bool | false | Use filename instead of package name for service naming | |
--verbose | -v | bool | false | Enable verbose logging |
--home | string | goctl template directory | ||
--remote | string | Remote template Git repository URL | ||
--branch | string | Remote template branch |
goctl rpc newQuickly create a complete RPC service project.
goctl rpc new <service_name> [flags]
Flags:
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--style | string | gozero | File naming style | |
--client | -c | bool | true | Generate RPC client code |
--module | string | Custom Go module name | ||
--verbose | -v | bool | false | Enable verbose logging |
--idea | bool | false | Generate IDE project marker | |
--name-from-filename | bool | false | Use filename instead of package name for service naming | |
--home | string | goctl template directory | ||
--remote | string | Remote template Git repository URL | ||
--branch | string | Remote template branch |
goctl rpc templateGenerate a proto file template.
goctl rpc template -o=<output_file> [flags]
Flags:
| Flag | Type | Description |
|---|---|---|
-o | string | Output file path (required) |
--home | string | goctl template directory |
--remote | string | Remote template Git repository URL |
--branch | string | Remote template branch |
--multiple)When a proto file contains multiple service definitions, the --multiple flag is required.
service SearchService {
rpc Search(SearchReq) returns (SearchReply);
}
service NotifyService {
rpc Notify(NotifyReq) returns (NotifyReply);
}
Directory differences with --multiple:
| Feature | Default mode | --multiple mode |
|---|---|---|
| Services per proto | Exactly 1 | 1 or more |
| Client directory | Named after service | Fixed client/ directory |
| Code organization | Flat structure | Grouped by service name |
--multiple=false (default) directory structure:
output/
├── greeterclient/
│ └── greeter.go
├── internal/
│ ├── logic/
│ │ └── sayhellologic.go
│ └── server/
│ └── greeterserver.go
└── ...
--multiple=true directory structure:
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)Use -I / --proto_path to specify additional proto search directories. Supported scenarios:
import "types.proto";import "common/types.proto";go_package values generate correct Go imports automatically# Search multiple directories for proto files
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
By default, the service name is derived from the proto package name (e.g., package user; → service name user). This allows multiple proto files to share the same package:
protos/
├── user_base.proto # package user;
├── user_auth.proto # package user;
└── user_profile.proto # package user;
All three files generate into a single user service.
To use the proto filename for naming (legacy behavior), add the --name-from-filename flag.
All three gRPC streaming patterns are supported:
service StreamService {
rpc ServerStream(Req) returns (stream Reply); // Server streaming
rpc ClientStream(stream Req) returns (Reply); // Client streaming
rpc BidiStream(stream Req) returns (stream Reply); // Bidirectional streaming
}
goctl automatically recognizes and handles Google protobuf well-known types:
| Proto Type | Go Type |
|---|---|
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 |
These types can be used directly as RPC parameter types — goctl generates the correct imports automatically.
See the example/ directory for 10 complete examples covering all generation scenarios.
| # | Example | Scenario |
|---|---|---|
| 01 | Basic service | Single service, no imports |
| 02 | Sibling import | Import from same directory |
| 03 | Subdirectory import | Import from subdirectory |
| 04 | Transitive import | A → B → C dependency chain |
| 05 | Multiple services | --multiple mode |
| 06 | Well-known types | Timestamp etc. in messages |
| 07 | External proto (same pkg) | External proto, same go_package |
| 08 | External proto (diff pkg) | External proto, different go_package |
| 09 | Google types as params | Empty/Timestamp as RPC parameters |
| 10 | Streaming | Server/client/bidirectional streaming |