grpc
π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
- Create the service definition and payload structure in the
.proto
file. - Generate the gRPC code from the
.proto
file. - Implement the server in one of the supported languages.
- Create the client that invokes the service thought the Stub.
- 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.
{{