Introduction to gRPC

Introduction to gRPC

2022, Dec 18    

Introduction

gRPC is a modern, high-performance, open source RPC (Remote Procedure Call) framework that can run in any environment. It uses HTTP/2 for transport, Protocol Buffers as the interface description language, and provides features such as authentication, bidirectional streaming and flow control, blocking or nonblocking bindings, and cancellation and timeouts.

There are several reasons why gRPC is often considered to be better than REST for building APIs:

Performance: gRPC uses HTTP/2, which is a binary protocol that is more efficient than the text-based HTTP/1.1 used in REST. This makes gRPC faster and more efficient, especially over high-latency networks.

Type safety: gRPC uses Protocol Buffers, which are a language- and platform-agnostic binary serialization format, to define the interface for a service. This makes it easier to catch errors early on and ensures that client and server implementations are always in sync.

Streamlined development: gRPC allows for bidirectional streaming, which means that both the client and server can send multiple messages back and forth as part of a single RPC call. This allows for more efficient communication and eliminates the need for workarounds such as long polling.

Language support: gRPC has official support for a wide range of languages, including C++, C#, Go, Java, Node.js, Objective-C, PHP, Python, Ruby, and Swift, making it easy to use in a variety of environments.

Compact payloads: Because gRPC uses Protocol Buffers, the payloads sent over the wire are smaller and more compact than those in REST, which typically use JSON. This can be especially beneficial for mobile applications that need to conserve bandwidth.

In summary, gRPC is a modern, high-performance RPC framework that offers a number of advantages over REST, including better performance, type safety, streamlined development, language support, and compact payloads. These features make it a great choice for building APIs in a variety of environments.

Server side implementation

To illustrate an example of a Kotlin implementation of a gRPC service, let’s assume that you have a gRPC service called “ GreetService” with a single method called “Greet” that takes a “GreetRequest” message as input and returns a “ GreetResponse” message. The “GreetRequest” message contains a field for the user’s name, and the “GreetResponse” message contains a field for the greeting.

Here is an example of how you could use this service in a Kotlin application:


import io.grpc.Server
import io.grpc.ServerBuilder
import io.grpc.stub.StreamObserver

import com.example.greet.GreetServiceGrpc
import com.example.greet.GreetRequest
import com.example.greet.GreetResponse

class GreetServiceImpl : GreetServiceGrpc.GreetServiceImplBase() {

    override fun greet(request: GreetRequest, responseObserver: StreamObserver<GreetResponse>) {
        val name = request.name
        val greeting = "Hello, $name!"

        val response = GreetResponse.newBuilder().setGreeting(greeting).build()
        responseObserver.onNext(response)
        responseObserver.onCompleted()
    }
}

fun main() {
    val server = ServerBuilder
        .forPort(50051)
        .addService(GreetServiceImpl())
        .build()

    server.start()
    println("Server started at port 50051")
    server.awaitTermination()
}

In this example, the GreetServiceImpl class extends the generated GreetServiceGrpc.GreetServiceImplBase class and overrides the “greet” method. This method takes a GreetRequest and a StreamObserver as arguments and returns a GreetResponse by building it with the greeting message. The main function creates a gRPC server and adds the GreetServiceImpl to it. The server is then started and waits for termination.

Web page consuming the service

Here is an example of how you could use this service in a ReactJS component:

import React, {useState, useEffect} from 'react';
import {GreetServiceClient} from './greet_service_pb';
import {GreetRequest, GreetResponse} from './greet_service_pb';

function GreetingComponent() {
    const [name, setName] = useState('');
    const [greeting, setGreeting] = useState('');

    useEffect(() => {
        const client = new GreetServiceClient('http://localhost:50051');
        const request = new GreetRequest();
        request.setName(name);

        const metadata = {'Authorization': `Bearer ${jwt}`}; // in case you need to pass the auth token 

        client.greet(request, metadata, (err, response) => {
            if (err) {
                console.error(err);
            } else {
                setGreeting(response.getGreeting());
            }
        });
    }, [name]);

    return (
        <div>
            <input
                type="text"
                value={name}
                onChange={(event) => setName(event.target.value)}
            />
            <p>{greeting}</p>
        </div>
    );
}

In this example, the GreetingComponent displays an input field for the user’s name and a paragraph element for the greeting. The useEffect hook is used to call the “Greet” method of the gRPC service when the name state variable changes. The callback function provided to the “Greet” method sets the greeting state variable with the response from the service.

This is just a basic example of how you can consume a gRPC service in a ReactJS component. You may need to modify the code to suit your specific use case and service.

gRPC REST
Protocol Buffers - smaller, faster JSON - text based, slower, bigger
HTTP/2 (lower latency) - from 2015 HTTP1.1 (higher latency) - from 1997
Bidirectional & Async Client => Server request only
Stream support Request/Response support only
API Oriented - “What” (no constraints - free design CRUD oriented (create, retrieve, update, delete/ POST,GET, PUT, DELETE)
Code generation through Protocol Buffers in any language - 1st class citzen Code generation throught OpenApi /Swagger (add-on) 2nd class citzen previous post
RPC based - gRPC does the plumbing for us HTTP verbs based - we have to write the plumbing or use a 3rd party library

gRPC ingtroduction