Skip to content

Create an RPC Service

This guide creates a user RPC service that an API gateway can call over gRPC.

  • protoc installed
  • protoc-gen-go and protoc-gen-go-grpc installed

Not installed? See Install protoc.

Terminal window
goctl rpc new user
cd user
go mod tidy

Goctl creates a .proto file and the full service skeleton:

user/
├── etc/
│ └── user.yaml
├── internal/
│ ├── config/config.go
│ ├── logic/
│ │ └── getuserlogic.go # ← implement this
│ ├── server/userserver.go # gRPC server adapter
│ └── svc/servicecontext.go
├── user/
│ └── user.pb.go # generated protobuf types
│ └── user_grpc.pb.go # generated gRPC stubs
├── user.go # entrypoint
└── user.proto # source of truth

Open user.proto:

syntax = "proto3";
package user;
option go_package = "./user";
service User {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
}
message GetUserRequest {
int64 id = 1;
}
message GetUserResponse {
int64 id = 1;
string name = 2;
}

Edit internal/logic/getuserlogic.go:

func (l *GetUserLogic) GetUser(in *user.GetUserRequest) (*user.GetUserResponse, error) {
// In production: query your DB via l.svcCtx
return &user.GetUserResponse{
Id: in.Id,
Name: "alice",
}, nil
}

Open etc/user.yaml — the default port is 8080:

Name: user.rpc
ListenOn: 0.0.0.0:8080

Run the RPC server:

Terminal window
go run user.go
# Starting rpc server at 0.0.0.0:8080...

Generate the RPC client stub that your API gateway will use:

Terminal window
goctl rpc protoc user.proto \
--go_out=./user \
--go-grpc_out=./user \
--zrpc_out=./client

In your API service’s servicecontext.go:

UserRpc userclient.User // inject the generated client

Then call it from a logic file:

resp, err := l.svcCtx.UserRpc.GetUser(l.ctx, &user.GetUserRequest{Id: 1})

go-zero handles connection pooling, load balancing, and circuit breaking automatically.

Terminal window
goctl rpc protoc user.proto \
--go_out=./user \
--go-grpc_out=./user \
--zrpc_out=.