Skip to main content

Build RPC

goctl rpc is an rpc service code generation module under goctl scaffolding, supporting proto template generation and rpc service code generation, through this tool to generate code you only need to focus on business logic writing without having to write some repetitive code. This allows us to focus on the business, thus speeding up the development efficiency and reducing the error rate of the code.

Features​

  • Easy to use
  • Fast development efficiency
  • Low error rate
  • Close to protoc

Quick start​

Way 1: Quickly generate greet services​

Generated by the command goctl rpc new ${servieName}

If you generate the greet rpc service.

  goctl rpc new greet

The code structure after execution is as follows:

.
β”œβ”€β”€ etc
β”‚ └── greet.yaml
β”œβ”€β”€ go.mod
β”œβ”€β”€ greet
β”‚ └── greet.pb.go
β”œβ”€β”€ greet.go
β”œβ”€β”€ greet.proto
β”œβ”€β”€ greetclient
β”‚ └── greet.go
└── internal
β”œβ”€β”€ config
β”‚ └── config.go
β”œβ”€β”€ logic
β”‚ └── pinglogic.go
β”œβ”€β”€ server
β”‚ └── greetserver.go
└── svc
└── servicecontext.go
tip

pb folder name (old version of the folder fixed to pb) said to be taken from the value of option go_package in the proto file last level of conversion in a certain format, if there is no such declaration, then the value from package, roughly code as follows.

google.golang.org/protobuf@v1.25.0/internal/strs/strings.go:71
  if option.Name == "go_package" {
ret.GoPackage = option.Constant.Source
}
...
if len(ret.GoPackage) == 0 {
ret.GoPackage = ret.Package.Name
}
ret.PbPackage = 'GoSanitized(filepath.Base(ret.GoPackage))'
...
tip

The name of the call layer folder is taken from the name of the service in the proto. If the name of this sercice is equal to the name of the pb folder, the client will be added after the srervice to distinguish it and make the pb and call separated.

if strings.ToLower(proto.Service.Name) == strings.ToLower(proto.GoPackage) {
callDir = filepath.Join(ctx.WorkDir, strings.ToLower(stringx.From(proto.Service.Name+"_client").ToCamel()))
}

Way 2: Generate rpc service by specifying proto​

  • Generate proto template
  goctl rpc template -o=user.proto
user.proto
syntax = "proto3";

package remote;

option go_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);
}
  • Generate rpc service code

     goctl rpc proto -src user.proto -dir .

Preparation​

  • Go environment is installed
  • protoc & protoc-gen-go are installed and environment variables are set
  • For more questions, see Notes

Usage​

rpc service generation usage​

goctl rpc proto -h
NAME:
goctl rpc proto - generate rpc from proto

USAGE:
goctl rpc proto [command options] [arguments...]

OPTIONS:
--src value, -s value the file path of the proto source file
--proto_path value, -I value native command of protoc, specify the directory in which to search for imports. [optional]
--dir value, -d value the target path of the code
--style value the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
--idea whether the command execution environment is from idea plugin. [optional]

Parameter description​

  • --src mandatory, proto data source, currently supports single proto file generation
  • --proto_path Optional, a native subcommand of protoc, used to specify where to look for proto import, multiple paths can be specified, e.g. goctl rpc -I={path1} -I={path2} ... ', which can be left out when there is no import. You don't need to specify the current proto path, it's already built-in, please refer to protoc -hfor the detailed usage of-I`.
  • --dir optional, default is the directory where the proto file is located, the target directory of the generated code.
  • --style optional, the output directory file naming style, see https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md for details.
  • --idea optional, whether to execute in the idea plugin, terminal execution can be ignored

What developers need to do​

Focus on business code writing, leave the repetitive, non-business related work to goctl, after generating good rpc service code, developers only need to modify

  • write configuration files in the service (etc/xx.json, internal/config/config.go)
  • Business logic writing in the service (internal/logic/xxlogic.go)
  • Writing of resource context in the service (internal/svc/servicecontext.go)

Caution​

  • proto does not support simultaneous generation of multiple files at the moment.
  • proto does not support external dependency package introduction, message does not support inline
  • Currently main file, shared file, handler file will be forced to overwrite, and developers need to write manually will not overwrite the generation, this category in the code header are
  // Code generated by goctl. DO NOT EDIT!
// Source: xxx.proto

Please be careful not to write business-like code in it as well.

proto import​

  • For requestType and returnType in rpc must be defined in main proto file, for message in proto can import other proto files like protoc.

error import​

greet.proto
syntax = "proto3";

package greet;

option go_package = "greet";

import "base/common.proto"

message Request {
string ping = 1;
}

message Response {
string pong = 1;
}

service Greet {
rpc Ping(base.In) returns(base.Out);// requestε’Œreturn δΈζ”―ζŒimport
}

Correctly import​

greet.proto
syntax = "proto3";

package greet;

option go_package = "greet";

import "base/common.proto"

message Request {
base.In in = 1;// ζ”―ζŒimport
}

message Response {
base.Out out = 2;// ζ”―ζŒimport
}

service Greet {
rpc Ping(Request) returns(Response);
}