gRPC
  • is a high-performance, open-source remote procedure call (RPC) framework
  • originally developed by Google
  • it lets services call methods on other services as if they were local functions with their parameters and return types — even when they’re running on different machines
  • uses protocol buffers to describe both the service interface and the structure of the payload messages
  • supports load balancing, tracing, health checking and authentication
  • operates over HTTP 2.0

gRPC - Allowed RPC Types

with their parameters and return types

Unary RPC

  • where the client sends a single request to the server and gets a single response back, just like a normal function call
  • rpc SayHello(HelloRequest) returns (HelloResponse){ }
    

Server Streaming RPC

  • where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. gRPC guarantees message ordering within an individual RPC call
  • rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){ }
    

Client Streaming RPC

  • where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them and return its response. Again gRPC guarantees message ordering within an individual RPC call
  • rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) { }
    

Bi-Directional Streaming RPC

  • where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved
  • rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){ }
    

gRPC - Example

Defining a Service

example service defined as a protocol buffer file:

// proto version 3
syntax = "proto3";

// A service definition with 2 RPCs
service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse);					// Unary RPC
  rpc BidiHello (stream HelloRequest) returns (stream HelloResponse);	// Bi-directional RPC
}

message HelloRequest {
  string greeting = 1;	// tag/field number 1 (should never change for backward compatibility)
}

message HelloResponse {
  string reply = 1;
}

the file above defines a Service with 2 RPCs:

  1. SayHello RPC - takes in a single message and returns a single message
  2. BidiHello RPC - takes in a stream of messages and returns a stream of messages

Generating Client & Server Code

protoc - is compiler that takes a .proto file and outputs code in the specified language

  1. if you haven’t installed the compiler, download the package and follow the instructions in the README
  2. further instructions now depends on the target language

Let’s use protoc to compile the hello-service.proto file and auto generate Go files:

protoc \
   --go_out=. \
   --go_opt=paths=source_relative \
   --go-grpc_out=.
   --go-grpc_opt=paths=source_relative \
   hello-service.proto

where:

  • —go_out=. - enables the Go Protobuf plugin
  • —go_opt=paths=source_relative - controls where the generated Protobuf message files are placed (i.e. hello-service.pb.go). source_relative means output files go next to the .proto file
  • —go-grpc_out=. - enables the Go gRPC plugin
  • —go-grpc_opt=paths=source_relative - controls where the generated gRPC client & server code are placed (i.e. hello-service_grpc.pb.go)

gRPC - Implementations

Resources