Multi Agent System Header

Understanding gRPC

RPC, Remote Procedure Call

RPC is a form of Client-Server Communication Method that uses a form of function call rather than usual http call.

In programming, a function call is when a piece of code runs and returns a value. In a local function call, the logic lives in the same memory space as your code. In Remote Procedure Call (RPC), the logic lives on a different server, but you call it exactly the same way you call a local function.

RPC tries to hide the network entirely. It lets you write code that says do_something(), and the system figures out how to send that command over the wire, run it, and bring the answer back. While in a HTTP/REST network we manually tell the HTTP client: "I want to perform GET action on the /users/123 resource."

Example: Lets imagine we want to calculate a sum.

Option A: HTTP/REST

We manually construct a network request URLs, methods (GET/POST), headers and status codes.

import requests 
# Explicitly building a network message
response = requests.get(
  ".../calculator/add?a=5&b=10"
) 
result = response.json()["value"]

Option B: RPC

We treat the server like an imported library. It looks like local code, but it executes remotely.


# Looks like a local function call
result = client.add(5, 10)

How it works conceptually?

  • Client: Calls a local function (the 'stub').
  • Stub: Packs the function name and arguments into a packet.
  • Network: Sends the packet to the server.
  • Server: Unpacks the packet, finds the real function, runs it, and sends the result back.
RPC Concept Diagram

gRPC

gRPC is a high-performance, open-source framework by Google which allows to connect services across different languages and platforms as if they were local function calls.

Unlike standard HTTP APIs (Rest) that typically send JSON over HTTP/1.1, gRPC is built on HTTP/2 and uses Protocol Buffers for data serializations. The HTTP/1.1 was incapable of sending multiple request or getting multiple response together in a single connection. A new layer, binary framing was introduced in HTTP/2. This binary layer does the encapsulation and encoding of the data. Hence, giving rise to gRPC.

HTTP/2 Binary Framing Layer

Protocol Buffers (The IDL)

Instead of JSON, gRPC uses Protocol Buffers. This is both an Interface Definition Language (IDL) and a binary serialization format. This is where we define a API contract in a .proto file.

As this is in the form of contract, both client and server side needs to have the same proto file, this will act as the intermediary contract for client to call any available functions from the server.

Browsers cannot speak native gRPC. They don't give enough control over HTTP/2 frames to support it. If we want to use gRPC from a Client side Component (frontend), we need a proxy called gRPC-Web to translate. gRPC shines in Server-to-server communication (including Next.js Server component talking to a Python backend).

A minimal microservice architecture using gRPC

By defining strict contracts using Protocol Buffers, services can evolve independently while maintaining type safety across boundaries. This architecture minimizes overhead and latency compared to traditional REST JSON communication.

HTTP/2 Binary Framing Layer

In an API Gateway architecture, gRPC and REST work together by treating the Gateway as a translation bridge. The Gateway exposes standard RESTful endpoints to the outside world, allowing browsers and mobile apps to communicate using familiar JSON over HTTP. When a request arrives, the Gateway "transcodes" the JSON payload into binary Protocol Buffers and forwards the request to internal microservices using high-performance gRPC. The response travels the reverse path: the microservice returns binary data, which the Gateway deserializes back into JSON for the client. This setup combines the accessibility of REST for the frontend with the speed, efficiency, and strict typing of gRPC for backend communication.

Read more