πŸ”—What is gRPC?

A remote procedure call (RPC) framework that by default uses protocol buffers as the Interface Definition Language (IDL). One of the initial benefits is the ability to be able to define and codify your service requirements via a .proto file.

It uses HTTP/2 for transport but is not yet available for use within the browser, therefore currently mainly in use for Inter-Process Communication (IPC) within microservices.

πŸ”—The workflow to create a gRPC service

  1. Create the service definition and payload structure in the .proto file.
  2. Generate the gRPC code from the .proto file.
  3. Implement the server in one of the supported languages.
  4. Create the client that invokes the service thought the Stub.
  5. Run the server and client(s).

πŸ”—.proto

The first step when working with protocol buffers is to define the structure for the data you want to serialize in a proto file: this is an ordinary text file with a .proto extension. Protocol buffer data is structured as messages, where each message is a small logical record of information containing a series of name-value pairs called fields. Here’s a simple example:

message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}

Once you have your service defined, you can utilise a command line compiler to generate stubs and code in multiple programming languages. So you can generate a client and server with the Go programming language, and then using the same .proto file generate a client/server with Ruby.

πŸ”—Install gRPC

To install this package, you need to install Go and setup your Go workspace on your computer. The simplest way to install the library is to run:

$ go get -u google.golang.org/grpc

Next, install the protoc plugin for Go:

$ go get -u github.com/golang/protobuf/protoc-gen-go

πŸ”—Hello World service example

Example of a service definition helloworld.proto using syntatx proto3

syntax = "proto3";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

The package value is used (conveniently) as the name of the Go package, in this case "helloworld"

The service Greeter exposes a method named SayHello if you would like more methods you could do something like this:

// The greeting service definition.
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

Now service Greeter exposes method SayHello and SayHelloAgain.

πŸ”—Syntax Explanation

Inside the service statement Greeter we state that we want a RPC service that as a SayHello method and that method accepts something of type HelloRequest and returns something of type HelloReply. The message statement defines what HelloRequest and HelloReply look like.

The numbers assigned to the property (e.g. both name = 1 and message = 1) are known as 'tags'. Effectively, tags with a number between 1 and 15 take one byte to encode where as tags between 16 and 2047 take two bytes to encode. The idea is that you should reserve the tags 1 through 15 for very frequently occurring message elements.

πŸ”—Create the code protoc

When using go you could keep this per repository in this case the package name is helloworld:

$ cd $GOPATH/src/github.com/<your thing>/helloworld

And then:

protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld

This will create go code in a file named helloworld.pb.go and can be used to create the server and client

πŸ”—When should you use REST?

If interoperability is your primary concern, nothing beats REST. There are no special technologies needed, and you can leverage all of the widely deployed infrastructure and tools that support the modern Web.

πŸ”—When should you use RPC?

If performance is your primary concern, RPC can provide an edge by leveraging serialized data formats and alternative transport mechanisms.

{{}}