gRPC in the Life of Microservices

Ramzi Alqrainy
The Startup
Published in
8 min readApr 26, 2020
Why milliseconds matter

The microservice architecture style has been taking the software industry by storm in the recent past and with some good arguments. It objectively delivers key benefits that make the resulting system resilient to failure and scalable at the desired level of granularity. In an enterprise scenario, a microservice architecture enables the use of heterogeneous technologies and different architectural patterns. It also dramatically simplifies deployment and allows the engineering department to more easily shape up a bespoke project that reflects the internal organization.

While REST is widely implemented, a newer communication technology, gRPC, has gained tremendous momentum across the cloud-native community.

What is gRPC?

gRPC is a modern, high-performance framework that evolves the age-old remote procedure call (RPC) protocol. At the application level, gRPC streamlines messaging between clients and back-end services. Originating from Google, gRPC is open source and part of the Cloud Native Computing Foundation (CNCF) ecosystem of cloud-native offerings.

A typical gRPC client app will expose a local, in-process function that implements a business operation. Under the covers, that local function invokes another function on a remote machine. What appears to be a local call essentially becomes a transparent out-of-process call to a remote service. The RPC plumbing abstracts the point-to-point networking communication, serialization, and execution between computers.

In cloud-native applications, developers often work across programming languages, frameworks, and technologies. This interoperability complicates message contracts and the plumbing required for cross-platform communication. gRPC provides a “uniform horizontal layer” that abstracts these concerns. Developers code in their native platform focused on business functionality, while gRPC handles communication plumbing.

gRPC offers comprehensive support across most popular development stacks, including Java, JavaScript, C#, Go, Swift, and NodeJS.

The battle between gRPC and HTTP

The following table offers a high-level comparison of features between gRPC and HTTP APIs with JSON.

gRPC Benefits

gRPC uses HTTP/2 for its transport protocol. While compatible with HTTP 1.1, HTTP/2 features many advanced capabilities:

  • A binary protocol for data transport — unlike HTTP 1.1, which sends data as clear text.
  • Multiplexing support for sending multiple parallel requests over the same connection — HTTP 1.1 limits processing to one request/response message at a time.
  • Bidirectional full-duplex communication for sending both client requests and server responses simultaneously.
  • Built-in streaming enabling requests and responses to asynchronously stream large data sets.

gRPC is lightweight and highly performant. It can be up to 8x faster than JSON serialization with messages 60–80% smaller. In Microsoft Windows Communication Foundation (WCF) parlance, gRPC performance exceeds the speed and efficiency of the highly optimized NetTCP bindings. Unlike NetTCP, which favors the Microsoft stack, gRPC is cross-platform.

Protocol Buffers vs JSON

Protocol Buffers

gRPC embraces an open-source technology called Protocol Buffers. They provide a highly efficient and platform-neutral serialization format for serializing structured messages that services send to each other. Using a cross-platform Interface Definition Language (IDL), developers define a service contract for each microservice. The contract, implemented as a text-based .proto file, describes the methods, inputs, and outputs for each service. The same contract file can be used for gRPC clients and services built on different development platforms.

Using the proto file, the Protobuf compiler, protoc, generates both client and service code for your target platform. The code includes the following components:

  • Strongly-typed objects, shared by the client and service, that represent the service operations and data elements for a message.
  • A strongly-typed base class with the required network plumbing that the remote gRPC service can inherit and extend.
  • A client stub that contains the required plumbing to invoke the remote gRPC service.

At runtime, each message is serialized as a standard Protobuf representation and exchanged between the client and remote service. Unlike JSON or XML, Protobuf messages are serialized as compiled binary bytes.

The Power of gRPC

Performance

gRPC messages are serialized using Protobuf, an efficient binary message format. Protobuf serializes very quickly on the server and client. Protobuf serialization results in small message payloads, important in limited bandwidth scenarios like mobile apps.

gRPC is designed for HTTP/2, a major revision of HTTP that provides significant performance benefits over HTTP 1.x:

  • Binary framing and compression. HTTP/2 protocol is compact and efficient both in sending and receiving.
  • Multiplexing of multiple HTTP/2 calls over a single TCP connection. Multiplexing eliminates head-of-line blocking.

In this test (application in GitHub), we can see a big difference between REST and gRPC. Not only has gRPC the advantage of a smaller payload from serialized data, but also the advantage of having a long-lasting client connection.

Remarkable is that in this test after every iteration gRPC takes on average less time for a server call, than on the other test, where on average, a call takes longer after every iteration.

Code generation

All gRPC frameworks provide first-class support for code generation. A core file to gRPC development is the .proto file, which defines the contract of gRPC services and messages. From this file gRPC frameworks will code generate a service base class, messages, and a complete client.

By sharing the .proto file between the server and client, messages and client code can be generated from end to end. Code generation of the client eliminates duplication of messages on the client and server, and creates a strongly-typed client for you. Not having to write a client saves significant development time in applications with many services.

Strict specification

A formal specification for HTTP API with JSON doesn’t exist. Developers debate the best format of URLs, HTTP verbs, and response codes.

The gRPC specification is prescriptive about the format a gRPC service must follow. gRPC eliminates debate and saves developer time because gRPC is consistent across platforms and implementations.

Streaming

HTTP/2 provides a foundation for long-lived, real-time communication streams. gRPC provides first-class support for streaming through HTTP/2.

A gRPC service supports all streaming combinations:

  • Unary (no streaming)
  • Server to client streaming
  • Client to server streaming
  • Bi-directional streaming

Deadline/timeouts and cancellation

gRPC allows clients to specify how long they are willing to wait for an RPC to complete. The deadline is sent to the server, and the server can decide what action to take if it exceeds the deadline. For example, the server might cancel in-progress gRPC/HTTP/database requests on timeout.

Propagating the deadline and cancellation through child gRPC calls helps enforce resource usage limits.

gRPC recommended scenarios

gRPC is well suited to the following scenarios:

  • Microservices — gRPC is designed for low latency and high throughput communication. gRPC is great for lightweight microservices where efficiency is critical.
  • Point-to-point real-time communication — gRPC has excellent support for bi-directional streaming. gRPC services can push messages in real-time without polling.
  • Polyglot environments — gRPC tooling supports all popular development languages, making gRPC a good choice for multi-language environments.
  • Network constrained environments — gRPC messages are serialized with Protobuf, a lightweight message format. A gRPC message is always smaller than an equivalent JSON message.

gRPC: The devil is in the detail

1. Limited browser support

It’s impossible to directly call a gRPC service from a browser today. gRPC heavily uses HTTP/2 features and no browser provides the level of control required over web requests to support a gRPC client. For example, browsers do not allow a caller to require that HTTP/2 be used, or provide access to underlying HTTP/2 frames.

gRPC-Web is an additional technology from the gRPC team that provides limited gRPC support in the browser. gRPC-Web consists of two parts: a JavaScript client that supports all modern browsers, and a gRPC-Web proxy on the server. The gRPC-Web client calls the proxy and the proxy will forward on the gRPC requests to the gRPC server.

Not all of gRPC’s features are supported by gRPC-Web. Client and bi-directional streaming isn’t supported, and there is limited support for server streaming.

2. Not human readable

HTTP API requests are sent as text and can be read and created by humans.

gRPC messages are encoded with Protobuf by default. While Protobuf is efficient to send and receive, its binary format isn’t human readable. Protobuf requires the message’s interface description specified in the .proto file to properly deserialize. Additional tooling is required to analyze Protobuf payloads on the wire and to compose requests by hand.

Features such as server reflection and the gRPC command line tool exist to assist with binary Protobuf messages. Also, Protobuf messages support conversion to and from JSON. The built-in JSON conversion provides an efficient way to convert Protobuf messages to and from human readable form when debugging.

Bringing gRPC to the Table of Microservices

At first, using the gRPC framework to connect distributed components may look like a step backward. After celebrating the advent of REST as the triumph of flexibility and decoupling, the industry is now carefully considering an approach centered on the concept of remote procedure calls (RPC). By design, an RPC requires some level of coupling between the caller and receiver.

In addition, the gRPC framework pushes well-defined messages, versioning and contracted endpoints. The framework runs over the newer HTTP/2 protocol and exchanges data in a binary format. Under the hood, a number of other, subtler differences exist that make gRPC worth a closer look. But is gRPC a better REST, or is it just particularly suited to a microservices scenario?

The point is that REST in itself is only the formalization of an ideal uniform interface to connect components. Inspired in 2000 by the way the Web was developing, REST never really achieved the goal of enabling any RESTful client to talk to any RESTful server regardless of knowing much of the details. How many RESTful Web APIs return 200 OK to report an error? And how many use the same POST verb to add, delete and update resources? REST definitely works, but beyond hype and fanfare it’s nothing more than a plain API exposed over HTTP that just requires an HTTP call to return a response. Each developer calling any endpoint of any declared REST API needs to know all of its details and, often, he is free to place calls in a different way than is documented and still get a valid response. As brutal as it may sound, there’s no (concretely applied) standard around REST.

As implemented in most real-world applications today, REST is basically a simplified, unstructured and improvable form of RPC in which HTTP elements (headers, query string, payloads, status codes) form the syntax of each call, and every call in every service may feature different characteristics.

So where does gRPC come from? It was originally developed by Google as a framework to better connect its large internal network of standalone services. That framework was open sourced in 2015 under the name gRPC, and is now owned by the Cloud Native Computing Foundation. The gRPC framework addressed precisely the scenario of most of today’s microservice-style architectures.

Conclusion

Until recently, the word REST has been used to label nearly any public endpoints exposed over the Web through the HTTP protocol. REST came with the promise that once resources are defined the entire public API results from the combination of resource names and HTTP verbs. As more verbs and resources are added, new and existing clients can just connect and place calls. This flexibility comes at an obvious cost — the lack of strict rules and contracts. This is just what gRPC brings to the table.

--

--

Ramzi Alqrainy
The Startup

Apache Solr Contributor | Slack Contributor | Speaker | Chief Technology Officer at The Chefz| Technical Reviewer for Big Data Books