gRPC is a popular RPC framework for building microservices that communicate efficiently. However, there are not very many good tutorials for how to structure your microservice code when using gRPC with Go. This repo attempts to define a pattern for adding a gRPC layer to an existing service definition.
Although it may be tempting to use Protobufs and autogenerated Go code as your service definition and business objects, this presents problems. It couples your service directly to gRPC and limits how your service may be defined (e.g. no proto support for maps).
A better way is to first define and implement your service as if it were just another package in a monolith. Then, add a separate implementation of that service that provides a gRPC transport layer. This keeps your code decoupled and easy to reason about.
service.go # service interface definition
\
- core/
service.go # implementation of the service interface that DOES NOT use gRPC.
\
- grpc/
service.proto # protobuf definition file for the gRPC service
service.pb.go # compiled protobufs
\
- client
client.go # gRPC client wrapper that implements the top-level service interface
\
- server
controller.go # controller that implements the gRPC service interface in service.pb.go
main.go # gRPC server executable that exposes the controller
To run the gRPC microservice, open a terminal in the root directory of this repo and run:
cd grpc/server
export GRPC_ADDR=":9000"
go build -o ./mysvc .
./mysvc
To talk to the gRPC service and see how its responses mirror using the core service directly, build the mysvctest
executable:
cd mysvctest
export GRPC_ADDR=":9000"
go build -o ./mysvctest .
# sample commands:
./mysvctest 1
./mysvctest 1 2 3
./mysvctest 5
./mysvctest 1 2 5