gRPC APIs

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

Unary RPC

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.

Server streaming RPC

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.

Client streaming RPC

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.

Bi-directional streaming RPC

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.

greeter.proto
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:

client.py
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.

Learn More