RPC Commands

[!TIP] This document is machine-translated by Google. If you find grammatical and semantic errors, and the document description is not clear, please PR

Goctl Rpc is a rpc service code generation module under goctl scaffolding, which supports proto template generation and rpc service code generation. To generate code through this tool, you only need to pay attention to the business logic writing instead of writing some repetitive code. This allows us to focus on the business, thereby speeding up development efficiency and reducing the code error rate.

Features

  • Simple and easy to use
  • Quickly improve development efficiency
  • Low error rate
  • Close to protoc

Quick start

The way one: Quickly generate greet service

Generated by the command goctl rpc new ${servieName}

Such as generating greet rpc service:

  1. goctl rpc new greet

The code structure after execution is as follows:

  1. .
  2. ├── etc // yaml configuration file
  3. └── greet.yaml
  4. ├── go.mod
  5. ├── greet // pb.go folder①
  6. └── greet.pb.go
  7. ├── greet.go // main entry
  8. ├── greet.proto // proto source file
  9. ├── greetclient // call logic ②
  10. └── greet.go
  11. └── internal
  12. ├── config // yaml configuration corresponding entity
  13. └── config.go
  14. ├── logic //business code
  15. └── pinglogic.go
  16. ├── server // rpc server
  17. └── greetserver.go
  18. └── svc // dependent resources
  19. └── servicecontext.go

① The name of the pb folder (the old version folder is fixed as pb) is taken from the value of option go_package in the proto file. The last level is converted according to a certain format. If there is no such declaration, it is taken from the value of package. The approximate code is as follows:

  1. if option.Name == "go_package" {
  2. ret.GoPackage = option.Constant.Source
  3. }
  4. ...
  5. if len(ret.GoPackage) == 0 {
  6. ret.GoPackage = ret.Package.Name
  7. }
  8. ret.PbPackage = GoSanitized(filepath.Base(ret.GoPackage))
  9. ...

For GoSanitized method, please refer to google.golang.org/protobuf@v1.25.0/internal/strs/strings.go:71

② The name of the call layer folder is taken from the name of the service in the proto. If the name of the sercice is equal to the name of the pb folder, the client will be added after service to distinguish between pb and call.

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

rpc one-click generation to solve common problems, see Error

The way two: Generate rpc service by specifying proto

  • Generate proto template

    1. goctl rpc template -o=user.proto
    1. syntax = "proto3";
    2. package remote;
    3. message Request {
    4. string username = 1;
    5. string password = 2;
    6. }
    7. message Response {
    8. string name = 1;
    9. string gender = 2;
    10. }
    11. service User {
    12. rpc Login(Request)returns(Response);
    13. }
  • Generate rpc service code

    1. goctl rpc proto -src user.proto -dir .

Prepare

  • Installed go environment
  • Protoc&protoc-gen-go is installed, and environment variables have been set
  • For more questions, please see Notes

Usage

rpc service generation usage

  1. goctl rpc proto -h
  1. NAME:
  2. goctl rpc proto - generate rpc from proto
  3. USAGE:
  4. goctl rpc proto [command options] [arguments...]
  5. OPTIONS:
  6. --src value, -s value the file path of the proto source file
  7. --proto_path value, -I value native command of protoc, specify the directory in which to search for imports. [optional]
  8. --dir value, -d value the target path of the code
  9. --style value the file naming format, see [https://github.com/tal-tech/go-zero/tree/master/tools/goctl/config/readme.md]
  10. --idea whether the command execution environment is from idea plugin. [optional]

参数说明

  • —src: required, the proto data source, currently supports the generation of a single proto file
  • —proto_path: optional. The protoc native subcommand is used to specify where to find proto import. You can specify multiple paths, such as goctl rpc -I={path1} -I={path2} ..., in You can leave it blank when there is no import. The current proto path does not need to be specified, it is already built-in. For the detailed usage of -I, please refer to protoc -h
  • —dir: optional, the default is the directory where the proto file is located, the target directory of the generated code
  • —style value the file naming format, see [https://github.com/tal-tech/go-zero/tree/master/tools/goctl/config/readme.md]
  • —idea: optional, whether it is executed in the idea plug-in, terminal execution can be ignored

What developers need to do

Pay attention to business code writing, hand over repetitive and business-unrelated work to goctl, after generating the rpc service code, developers only need to modify.

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

Precautions

  • proto does not support the generation of multiple files at the same time
  • proto does not support the introduction of external dependency packages, and message does not support inline
  • At present, the main file, shared file, and handler file will be forcibly overwritten, and those that need to be written manually by the developer will not be overwritten and generated. This category has the code header

    1. // Code generated by goctl. DO NOT EDIT!
    2. // Source: xxx.proto

    If it contains the DO NOT EDIT logo, please be careful not to write business code in it.

proto import

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

proto example:

Wrong import

  1. syntax = "proto3";
  2. package greet;
  3. import "base/common.proto"
  4. message Request {
  5. string ping = 1;
  6. }
  7. message Response {
  8. string pong = 1;
  9. }
  10. service Greet {
  11. rpc Ping(base.In) returns(base.Out);// request and return do not support import
  12. }

Import correctly

  1. syntax = "proto3";
  2. package greet;
  3. import "base/common.proto"
  4. message Request {
  5. base.In in = 1;
  6. }
  7. message Response {
  8. base.Out out = 2;
  9. }
  10. service Greet {
  11. rpc Ping(Request) returns(Response);
  12. }

Guess you wants