gRPC APIs
gRPC (grpc.io) is a high performance, language-agnostic RPC framework.
It is widely used in microservices architectures, to connect services in and across data centers, as well as in last mile communications to devices, mobile apps and browsers applications.
gRPC is built on the HTTP/2 standard and uses Protocol Buffers (Protobuf) as its interface definition language (IDL) to define service methods and message types.
Why gRPC
gRPC provides several key benefits that make it a powerful choice for building modern distributed systems:
-
Support for multiple programming language gRPC supports multiple programming languages, including but not limited to C++, Java, Python, Go, Ruby, and more. This allows teams to build services in different languages and have them communicate seamlessly.
-
Strongly-Typed Contracts gRPC uses Protocol Buffers to define service methods and messages. This enforces a strongly-typed contract between services, reducing the chances of errors caused by mismatched data types or structures.
-
Efficient Communication Built on HTTP/2, gRPC supports multiplexed streams, which means multiple requests can be sent and received concurrently on the same connection. This reduces latency and improves overall efficiency of the service-to-service communication.
-
Bidirectional Streaming gRPC supports different types of streaming: Unary (single request/response), Server streaming (single request, multiple responses), Client streaming (multiple requests, single response), and Bidirectional streaming (multiple requests/responses). This flexibility allows for more complex communication patterns, such as real-time data streaming.
-
Built-in Authentication and Security gRPC provides built-in support for authentication mechanisms such as SSL/TLS and OAuth, ensuring secure communication between services. This is especially critical in environments where sensitive data is transmitted.
Use Cases
gRPC is versatile and can be used in various scenarios, including:
-
Microservices Communication: gRPC is ideal for communication between microservices due to its efficiency and language-agnostic nature.
-
Real-Time Data Streaming: With support for bidirectional streaming, gRPC can handle real-time data flows, such as live updates or sensor data transmission.
-
Mobile Backend Services: gRPC’s compact and efficient binary format makes it suitable for mobile devices with limited bandwidth.
Communication Patterns
gRPC supports four different communication patterns, depending on how the client and server communicate, allowing for the exchange of single or multiple messages within a single RPC call.
Let’s go through them one by one, to see how each type works.
Unary RPC
In a unary RPC, the client sends a single request to the server, and the server sends a single response back:
- Client → Sends a single request.
- Server → Replies with a single message.
This is the simplest form of RPC and it is similar to:
- A typical HTTP request-response model.
- A traditional function invocation, but over the network.
Server Streaming RPC
In a server streaming RPC, the client sends a single request to the server, and the server responds with a stream of data over time:
- Client → Sends single request.
- Server → Replies with a stream of multiple messages.
This kind of RPC has the following benefits:
- The client can process each message as it’s received, without waiting for the entire response.
- The server has the flexibility to generate and send messages at its own pace, as they’re ready, without needing to wait for the full dataset or response.
- Allows the server to send updates about new events or real-time notifications, even when the recipient is behind a firewall (thanks to the fact that the client initiated the connection through the initial request).
Client Streaming RPC
In a client streaming RPC, the client sends a stream of messages to the server, and the server responds with a single message once it has received all client messages:
- Client → Sends multiple requests as a stream.
- Server → Replies with a single response after processing the stream.
This type of RPC is useful for uploading large data sets in chunks, where the server can processes the data once it receives the entire stream, or chunk by chunk as the client sends them.
Bi-directional Streaming RPC
In a bi-directional streaming RPC, both the client and the server can send multiple messages to each other. Each side can send messages independently, and the messages operate asynchronously:
- Client → Sends multiple requests as a stream.
- Server → Replies with multiple responses as a stream.
This type of RPC allows both the client and the server to send data back and forth continuously, and it’s useful in:
- Real-time applications like chat or video streaming.
- All use-cases listed in server-streaming and client-streaming, when the other part needs to acknowledge or reply while receiving chunks of data.
- When one of the two communication endpoints is behind a firewall as it allows the protected endpoint to initiate the connection through the initial request, and then allows multiple messages in both directions inside the established connection.
How gRPC Works
gRPC works by the concept of a Service Definition written using protocol buffers. This concept is useful to learn about the APIs itself and also to generate the custom libraries in your preferred programming language to interact with the APIs.
So, when you want to generate a library, you have to use the protoc
tool and this section shows how to do so by providing an example in Python.
Service Definition
A gRPC service is defined using Protocol Buffers. The service definition includes the RPC (Remote Procedure Call) methods that can be invoked, along with the message types used for requests and responses.
syntax = "proto3"
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Creating a Library in Python
Now, let’s describe how to generate a library in Python that allows you to interact with gRPC services.
Code Generation
Once the service is defined, the Protocol Buffers compiler (protoc) generates code in the target language(s). For example, if you’re working in Python, you can generate the client code using the following command:
protoc --python_out=. --grpc_python_out=. greeter.proto
This command generates two files:
greeter_pb2.py
: Contains the data structures for the request and response messages.greeter_pb2_grpc.py
: Contains the client classes.
Using the Python Client Library
After generating the client code, you can use it to interact with the gRPC service. Below is an example of how to use the generated client library in Python to invoke the SayHello()
method on a remote server:
import grpc
import greeter_pb2
import greeter_pb2_grpc
def run():
# Create a channel to connect to the server
with grpc.insecure_channel('localhost:50051') as channel:
# Create a stub (client)
stub = greeter_pb2_grpc.GreeterStub(channel)
# Create a request object
request = greeter_pb2.HelloRequest(name='World')
# Call the SayHello method and get the response
response = stub.SayHello(request)
print("Greeter client received: " + response.message)
if __name__ == '__main__':
run()
In this example:
- A gRPC channel is created to connect to the server running on localhost at port 50051.
- A stub (client) is created from the GreeterStub class generated by protoc.
- The client creates a HelloRequest message and calls the SayHello() method on the stub, sending the request to the server.
- The server processes the request and sends back a HelloReply message, which the client prints out.
Interacting With gRPC APIs
There are two ways to interact with gRPS APIs:
- Via grpcurl
- Via a custom library
The above section shows how to create a custom library in Python.
The following section describes the basics of grpcurl
.
grpcurl
basics
grpcurl
is a command-line tool designed to make interacting with gRPC services easier by allowing you to query gRPC APIs without needing to write any client code.
Similar to curl
for HTTP-based APIs, grpcurl
can send requests to a gRPC server, list available methods, and make RPC calls directly from the command line. This tool is particularly useful when you need to quickly test or debug gRPC APIs.
Installing grpcurl
To install grpcurl
, download it from here, based on your Operating System and computer architecture.
Using grpcurl
Using grpcurl
is a straigthforward process.
For example, to list all the methods available in a gRPC service, you can run the following:
grpcurl -plaintext localhost:50051 list
As another example, to make a specific API call, such as querying a GetUser
method that takes a user ID, you can use the following:
grpcurl -plaintext -d '{"user_id": 12345}' localhost:50051 service.User/GetUser
Learn more about how to use it here.