What is gRPC?
10 minWant a faster way to deploy your gRPC applications? We added native gRPC support to the platform. Jump into this blog post to learn about this modern RPC framework and start taking your applications to the next level!
gRPC is an open source remote procedure call (RPC) framework that enables client and server applications to communicate with each other remotely and transparently.
In this blog post, we are going to discuss gRPC. First, we’ll talk about RPCs and why they are important. Then we’ll explain how gRPC works, taking a closer look at protocol buffers and the architecture of gRPC. After discussing the benefits and one big drawback to gRPC, we’ll discuss when to use gRPC and see who is using it. Finally, we'll look at how to develop and deploy applications using it.
- RPCs and REST are vital for connecting distributed services
- What is gRPC?
- Benefits of gRPC and protobufs
- Typical use cases for gRPC
- How to develop Java, Python, Ruby, Node, PHP, and Go applications using gRPC?
- Deploy gRPC applications globally
RPCs and REST are vital for connecting distributed services
Computing systems are continuously talking with each other to perform tasks. Think about each time you perform a Google search — you are asking Google servers to do some work for you and return the results to you. Services running on different computers or platforms need a standardized way to exchange information in order to work together.
Two of the most widely used mechanisms to expose APIs are Remote Procedure Call (RPC) and Representational State Transfer (REST). RPC is a programming model that enables client applications to call functions or procedures on remote server applications as if they were local function calls. REST is an architectural design that we discussed in our blog post on understanding different API architectures.
Both enable developers to build distributed software systems that communicate with each other seamlessly and reliably. This is increasingly important in today's world of cloud computing and microservices, where different pieces of code often run in different environments and need to work together seamlessly to deliver value to end users.
What is gRPC?
gRPC is an open source remote procedure call (RPC) framework developed by Google and is now a CNCF project. In this section, we will discuss gRPC's use of protocol buffers, its architecture, and its benefits.
By the way, if you are wondering what the g stands for in gRPC, it stands for something different with every gRPC release: https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md.
Protocol buffers
gRPC uses protocol buffers as both its Interface Definition Language (IDL) and as its underlying message interchange format. Protocol buffers, aka protobufs, are a language-agnostic protocol for serializing structured data and they can be used between different programming languages. They are strongly typed, which ensures that the data is consistent and well-formed across different applications and services.
Using proto files as contracts
The protobuf file is the definition of the contract between the client and the server.
To use protocol buffers, the first step is to define the data structure that you want to serialize in a proto file, which is a plain text file with a .proto
extension.
Here is an example proto file for a login request:
Automatic code generation with protoc
After defining the data structures, all you need is to use the protocol buffer compiler protoc
. It takes as input your proto files and generates all of the plumbing code needed to send and receive gRPC requests.
Architecture
Like other RPC systems, gRPC is based on the practice of defining a service and specifying the methods that can be remotely called with their parameters and return types.
Here is the explanation and architecture schema from the gRPC doc.
On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a stub (referred to as just a client in some languages) that provides the same methods as the server.
Photo courtesy of gRPC under the CC BY 4.0 license.
Client and server applications can be written in any of gRPC’s supported languages: Go, Python, Node, Python, Ruby, and more. If you want to learn how to implement gRPC into your applications, jump ahead to the section on developing applications using gRPC.
Benefits of gRPC and protobufs
Performance: Protobufs use a binary data representation, enabling data packets to be transported faster than other formats like JSON or XML. This is because binary data is more compact and easier to parse than text-based formats. Protobufs are also more efficient to serialize and deserialize, which can lead to better performance in some cases.
HTTP/2 transport protocol: gRPC runs on HTTP/2, which offers several advantages over HTTP 1.1, such as real-time communication and greatly improved network efficiency. HTTP/2 supports bi-directional streaming, multiplexing, and more.
- Bi-directional streaming is ideal for real-time applications as it enables clients and servers to send and receive data without waiting for a request or response to be completed before sending the next message. This can be vital for achieving high performance and low latency in certain use cases.
- Multiplexing enables multiple requests and responses to be sent concurrently over a single TCP connection. Instead of opening a new connection for each request, HTTP/2 can send multiple requests simultaneously over the same connection, and the server can respond to them in any order.
Automatic code generation: One of the major benefits of using protobufs with gRPC is that they automatically generate code for different languages, which makes it easier to create client and server applications that use gRPC. This saves time and effort, as developers do not need to write code to serialize or deserialize data between different systems.
Protobuf strict contracts prevent errors: gRPC uses protobufs to define APIs, data structures, and endpoints. This results in strict contracts between the client and server, as the contracts are strongly typed. These strict contracts help prevent errors and unexpected behavior, as both the client and server know exactly what data to expect and how to handle it.
Smooth migrations with versioning: Another benefit of using gRPC is the ability to smoothly migrate to new versions of the API while maintaining backward compatibility. Microsoft has a good resource on gRPC versioning that can be helpful for more information and best practices.
gRPC drawbacks: Browser compatibility, heavier machinery, and testing
The main reason why we don't see most websites use gRPC is the lack of support for it in browsers. A few initiatives working on this include:
- gRPC Gateway: A layer that you put in front of your gRPC APIs that translates gRPC to HTTP and HTTP to gRPC. Fun fact, we are using this! In our case, the Koyeb console talks to the Koyeb API in HTTP, but the API actually uses gRPC.
- gRPC-Web: A JavaScript library that enables browser clients to communicate with gRPC services using Envoy proxies by default.
Another drawback of gRPC is that due to its use of protocol buffers, it is overall heavier machinery. Plus testing is not as simple as with HTTP where you can run a curl
to test requests and write the data in JSON. Testing requests in gRPC requires a proto
file because you cannot write the data in binary directly.
Typical use cases for gRPC
- Replace REST APIs as long as the client is not a browser. Protocol buffers provide a way to define API contracts, which ensures client and server applications agree on how to exchange information.
- Inter-service communication. Regardless of which framework or language the services are written in, gRPC enables them to communicate with each other transparently. This is especially advantageous for large organizations that need interoperability between different parts of their system.
- Authentication mechanism. gRPC provides built-in support for various authentication mechanisms and lets you plug in your own, making it easy to secure communication between services.
- Optimizing payload format: gRPC typically uses protocol buffers for data serialization. It is also possible to use JSON and other formats when needed.
- Anywhere you are using RPC.
gRPC in action: A real-world example
Imagine that you're building a ride-hailing application that has two services: one is an app for the riders written in Go and another is an app for the drivers written in Java. Both services need to exchange information about ride requests, driver availability, and ride status updates. This is a great opportunity to use gRPC!
The rider app exposes a gRPC service that allows it to request rides and get ride status updates. The server-side implementation of this service defines the methods that can be remotely called, along with their input and output parameters, using protocol buffers. Once the service is defined, you can use the Protocol Buffer compiler (protoc) to generate server-side code that implements the service interface.
On the client side, the rider app has a generated stub that provides the same methods as the server. Protocol buffers' code generation also automatically generates this client stub. When the rider app calls a method on the stub, the gRPC framework handles the details of serializing the input parameters into binary format and sending them over the network to the server.
By using gRPC, both services can communicate with each other seamlessly and efficiently, despite being written in different programming languages and running on different machines.
Who is using gRPC?
Lots of companies are using gRPC to connect their services and improve performance, including Square, Cisco, Netflix, Uber, Dropbox, and more. If you're interested in reading more about these use cases, some of their engineering teams wrote in-depth blog posts.
- Uber wrote about changing their protocol from SSE (HTTP1.1) to gRPC-based bidirectional streaming.
- Dropbox published a blog post about their migration to gRPC.
- Netflix also wrote about how they use gRPC for their backend-to-backend communication.
How to develop Java, Python, Ruby, Node, PHP, and Go that use gRPC?
Developing apps with gRPC is a powerful way to streamline communication between services and create efficient, high-performance systems.
If you want to learn how to use gRPC in your application development, the following documentation explains how to implement gRPC in a variety of programming languages:
- Go applications
- Java applications
- Node applications
- PHP applications
- Python applications
- Ruby applications
Good news: If you are using these languages, they are natively supported on the Koyeb platform. We are making it easier to deploy gRPC applications globally. Next, we’ll explore how to deploy your gRPC applications on the platform and use gRPC at the edge for public services and inside the service mesh for private ones.
Deploy gRPC applications globally
Deploying gRPC applications globally is a challenge that requires managing load balancing, service discovery, error handling, and more. 😱
With built-in gRPC support, the Koyeb serverless platform is making it easier than ever to deploy gRPC applications globally. Your applications can use gRPC when communicating between services running inside the built-in service mesh, as well as at the edge for public services. All with zero configuration from you. 🚀
Further reading
Suggestions to improve this blog post? Join us on the community platform to chat!