08 · gRPC & Alternative Protocols¶
REST over HTTP/JSON isn't the only way to build an API. This module covers gRPC and other protocols you'll meet in the wild, and when they beat REST.
gRPC: HTTP/2 + Protocol Buffers¶
gRPC defines a service in a .proto file, generates strongly-typed
client and server code in almost any language, and communicates using
compact binary Protocol Buffers over HTTP/2.
syntax = "proto3";
service OrderService {
rpc GetOrder (GetOrderRequest) returns (Order);
rpc StreamOrderUpdates (GetOrderRequest) returns (stream Order);
}
message GetOrderRequest { int32 id = 1; }
message Order {
int32 id = 1;
double total = 2;
string status = 3;
}
A generated client calls this like a local function, not an HTTP request:
Under the hood this is still a request over the network — but the developer writes no URL, no JSON parsing, no manual serialization.
Why gRPC over REST/JSON¶
- Performance — binary Protobuf is smaller and faster to (de)serialize than JSON; HTTP/2 multiplexes many calls over one connection.
- Strong contracts — the
.protofile is the single source of truth for types, generated on both client and server, so mismatches are caught at compile time, not at runtime like a malformed JSON body. - Native streaming —
stream Orderabove is a first-class bidirectional or server-streaming call; REST has no equivalent without bolting on SSE or WebSockets.
Why REST still wins for public/browser-facing APIs¶
- Browsers can't natively speak gRPC (it needs HTTP/2 trailers browsers don't fully expose) — gRPC-Web exists but adds a proxy layer.
- REST/JSON is debuggable with
curland readable by a human; a Protobuf wire message is not. - Public third-party integrators expect REST; gRPC assumes both sides control their codegen pipeline, which is realistic inside one company, less so across organizations.
gRPC is the common choice for internal service-to-service calls in a microservices architecture (module 1, Level 4); REST/JSON stays the default for public and browser-facing APIs.
Other alternatives worth knowing¶
WebSockets — a persistent, full-duplex connection for real-time, bidirectional communication (chat, live dashboards):
const ws = new WebSocket("wss://api.example.com/v1/orders/42/stream");
ws.onmessage = (event) => console.log(JSON.parse(event.data));
Server-Sent Events (SSE) — one-way server → client streaming over plain HTTP, simpler than WebSockets when the client never needs to send messages back over the same connection:
event: status_changed
data: {"status": "shipped"}
event: status_changed
data: {"status": "delivered"}
MQTT — a lightweight pub/sub protocol built for constrained IoT devices over unreliable networks; overkill for a typical web API, the right choice for a fleet of sensors.
Worked example: picking a protocol¶
A company has a public REST API for customers, and internally, a fleet of a dozen microservices calling each other thousands of times a second, plus a live "order status" feed customers want to watch update in real time.
- Customer-facing CRUD → REST/JSON, cacheable, debuggable, matches customer expectations.
- Service-to-service calls → gRPC, for the performance and strong typing at high call volume.
- Live order-status feed → SSE, because it's one-directional (server informs client) and simpler to operate than WebSockets for that shape of problem.
How It Actually Works¶
gRPC's speed advantage over JSON-over-REST comes from two stacked mechanisms: HTTP/2 multiplexes many requests over one TCP connection (no repeated handshakes, no head-of-line blocking at the connection level), and Protocol Buffers encode messages as a compact binary wire format keyed by field numbers rather than string field names — so there's no text parsing, no whitespace, and the receiver only needs the numbered schema (the .proto file) to decode it deterministically. That efficiency is exactly the tradeoff: a REST/JSON response is human-readable in a browser's network tab and debuggable with curl, while a gRPC binary payload requires the schema and tooling to even inspect — which is why public, browser-facing APIs still lean REST even where gRPC would be objectively faster on the wire.
Exercise¶
- Why can't a browser call a gRPC service directly the way it calls a
REST endpoint with
fetch? - Give one scenario where SSE is the better choice over WebSockets, and one where it's the wrong choice.
- A
.protofile changes a field's type fromint32tostring. Is this breaking in the same way a JSON REST field-type change is (module 6)? Why does Protobuf field numbering matter for compatibility even when types don't change? - Explain why gRPC is more common for internal microservice traffic than for public developer-facing APIs.