gRPC
Last updated
Last updated
gRPC is a modern, open source remote procedure call (RPC) framework that can run anywhere. It enables client and server applications to communicate transparently, and makes it easier to build connected systems.
Read the longer Motivation & Design Principles post for background on why we created gRPC.
The main usage scenarios:
Low latency, highly scalable, distributed systems.
Developing mobile clients which are communicating to a cloud server.
Designing a new protocol that needs to be accurate, efficient and language independent.
Layered design to enable extension eg. authentication, load balancing, logging and monitoring etc.
REST uses the resources for its design. The first task at hand when developing a RESTful API is to translate your domain into resources uniquely identified by a URL, e.g. /user. Then we map standard HTTP verbs POST, GET, PUT and DELETE to CRUD actions: POST for creations, GET for retrievals, PUT for updates, and finally DELETE for deletions.
gRPC is built on the core principle that we must use Services not Objects, and Messages not References. In other words, in gRPC we start the process by defining our services and their message types. We use clear interfaces that maps directly to our business functions and programming concept like interfaces or methods. No need for translations. gRPC is all about APIs, not resources.
Design a user CRUD in REST is easy, but things get complicated when we want to "lock a user for a while". This is easily done by using gRPC:
REST could be contract-first or contract-last. When using a contract-last approach, developers start by coding the API in their preferred language and later they auto-generate a contract from it which serves as documentation. This is probably the easiest approach for a small team. For larger teams, contract-first is typically more suitable. In this case, the contract of the API is defined upfront and some portions of the implementation are auto-generated from it. Each team can then work independently by sticking to the predefined contract. In both cases, you will be left with having to choose which language and toolset to use to define and auto-generate contracts or code. There are a lot of valid options like Swagger, now known as OpenAPI, and RAML but once again there’s no predefined standard.
gRPC uses protocol buffers by default as their Interface Definition Language (IDL) and serialization toolset. It is strictly contract-first.
REST uses JSON most, it is the most popular payload format and can be considered the de facto standard in the industry. Its main advantages are that it is easy to read and well supported in most languages. The main disadvantages of JSON are that it is not schema driven, it has no typing, and it’s not versioned. All these drawbacks lead to serialization issues which can have disastrous consequences, especially in microservice-oriented architectures where failures cascade. The serialization toolset needs to process the entire payload and infer the type of each property. Needless to say, it is very common for the inferred type to be wrong.
gRPC uses Protocol buffers (protobufs) by default. The data structure is defined upfront and the code to handle serialization and deserialization is auto-generated by the toolset for free. It is strongly typed and extensible. As you can see below, each field in the message definition has a type and unique number. Typing removes any guessing when serializing data. The numbers are used to identify the fields in the message binary format and should never be changed when in use. They are Google’s approach to API versioning. If you intend to add new fields in the future, you will simply assign them a new number. Existing clients and servers will be able to identify fields they know by their numbers and ignore the rest.
If we want to remove some fields from the message definition, we need to ensure that their field name and number are not reused in the future by using the reserved keyword as shown above. This is necessary to ensure retro-compatibility by disallowing type changes for a given field name or number.
HTTP RESTful APIs are synchronous and unary by default since they are built around the request-response model available in HTTP/1.x. The client sends a single request and waits until it receives a response.
gRPC supports both asynchronous and synchronous processing by taking full advantage of HTTP/2. You can use it to perform Unary RPC, Server Streaming RPC, Client Streaming RPC or Bidirectional RPC. It virtually covers all imaginable use cases, from simple CRUD operation to high throughput streaming used in storage systems and big data contexts which requires the best possible performance.
The REST architectural style does not give guidance on authentication and authorization concerns. For years, APIs have been secured using custom and inefficient auth schemes. Lately, the advent of SAML 2.0, OAuth 2.0 and OpenID Connect 1.0 eased the standardization process improving security and interoperability across different providers.
gRPC has fully integrated pluggable authentication. It has two built-in auth strategies: certificate based which makes uses of SSL/TLS certificates; and token based which leverages Google OAuth 2.0 tokens. It is also extremely easy to extend gRPC support for other authentication mechanisms. Its Authentication API revolves around the unified concept of a Credentials object. Developers can then leverage the Credentials Plugin API to plug in their own type of credentials.
gRPC is designed for both high-performance and high-productivity design of distributed application.
Protobufs are not human readable. This is possibly the biggest drawback of gRPC. Developer and quality assurance specialists which are used to inspect HTTP request and response payloads over the wire need to change debugging approach. Moreover, it is not possible to invoke an endpoint just by typing its address on the browser.
User might not be ready to switch from REST to gRPC: backward compatibility, cost has been put in REST development, etc. So, gRPC developers incorporated the concept of an HttpRule in the service definition. HttpRule defines the mapping of an RPC method to one or more HTTP REST API methods. The mapping specifies how different portions of the RPC request message are mapped to URL path, URL query parameters, and HTTP request body.
Finally, the gRPC community has created the grpc-gateway plugin for protoc, the protobuf code generator tool. It reads the gRPC service definition with its custom HTTP options and automates the provision of the APIs in both gRPC and RESTful style at the same time.
You get the best of both worlds with little effort. This is particularly useful for services exposed to the World Wide Web. You can continue leveraging RESTful HTTP APIs for your client integrations, while translating their requests to gRPC for internal communication.
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.
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.
Other frameworks are recommended over gRPC in the following scenarios:
Browser accessible APIs – gRPC isn't fully supported in the browser. gRPC-Web can offer browser support, but it has limitations and introduces a server proxy.
Broadcast real-time communication – gRPC supports real-time communication via streaming, but the concept of broadcasting a message out to registered connections doesn't exist. For example in a chat room scenario where new chat messages should be sent to all clients in the chat room, each gRPC call is required to individually stream new chat messages to the client. SignalR is a useful framework for this scenario. SignalR has the concept of persistent connections and built-in support for broadcasting messages.
Inter-process communication – A process must host an HTTP/2 server to accept incoming gRPC calls. For Windows, inter-process communication pipes is a fast, lightweight method of communication.