...

/

Developing gRPC Services and Clients

Developing gRPC Services and Clients

Understand how to build and use gRPC clients and servers.

gRPC provides an entire framework for RPCs based on HTTP and utilizing Google’s protocol buffer format, a binary format that can convert into JSON but provides both a schema and, in many cases, a 10x performance improvement over JSON.

There are other formats in this space, such as Apache’s Thrift, Cap’n Proto, and Google’s FlatBuffers. However, these are not as popular and well supported, or satisfy a particular niche, while also being hard to use.

gRPC, like REST, is a client/server framework for making RPC calls. Where gRPC differs is that it prefers a binary message format called protocol buffers (proto for short). This format has a schema stored in a .proto file that is used to generate the client, server, and messages in a native library for the language of our choice using a compiler. When a proto message is marshaled for transport on the wire, the binary representation will be the same for all languages.

Let's talk more about protocol buffers, gRPC's message format of choice.

Protocol buffers

Protocol buffers define RPC messages and services in one location and can generate a library for every language with the proto compiler. Protocol buffers have the following advantages:

  • They write once and generate for every language.

  • Messages can be converted to JSON as well as binary.

  • gRPC can use a reverse proxy to provide REST endpoints, which is great for web apps.

  • Binary protocol buffers are smaller and can encode/decode at 10x the rate of JSON.

However, protocol buffers do have some negatives:

  • We must regenerate the messages on any change to the .proto file to get the changes.

  • Google's standard proto compiler is painful and confusing to use.

  • JavaScript does not have native support for gRPC, even though it supports protocol buffers.

Tooling can help with some of the negatives, and we will be using the new Buf tools to help with proto generation.

Let's take a look at what a protocol buffer .proto file looks like for a QOTD service:

Press + to interact
syntax = "proto3";
package qotd;
option go_package = "github.com/[repo]/proto/qotd";
message GetReq {
string author = 1;
}
message GetResp {
string author = 1;
string quote = 2;
}
service QOTD {
rpc GetQOTD(GetReq) returns (GetResp) {};
}

The code above works as follows:

  • Line 1: The syntax keyword defines which version of the proto language we are using. The most common version is proto3, the third iteration of the language. All three have the same wire format but have different feature sets and generate different language ...