Articles

gRPC vs REST: Choosing an API Style

gRPC uses binary Protocol Buffers over HTTP/2 for fast, typed service calls; REST uses JSON over HTTP for accessible, resource-based APIs. How to pick.

Chisato Chisato · · 4 min read
Abstract illustration of connected API nodes

gRPC and REST are two different philosophies for designing an API. REST models an API as a set of resources — users, orders, invoices — that clients fetch or modify with standard HTTP verbs and JSON. gRPC models an API as a set of remote procedure calls defined by a strict contract, serialized as compact binary Protocol Buffers and sent over HTTP/2. Neither is a strict upgrade of the other: REST optimizes for accessibility and broad compatibility, gRPC optimizes for speed and typed contracts between services you control on both ends.

How each one models communication

A REST API treats every entity as a resource with a URL, and reuses a small set of HTTP verbs to act on it: GET /users/123 reads a user, POST /users creates one, DELETE /users/123 removes one. The response body is usually JSON, readable by a human without any special tooling, and the “contract” between client and server is often informal — described in documentation or an OpenAPI spec, but not strictly enforced by the protocol itself.

gRPC instead treats the API as a set of function calls defined in a .proto file: rpc GetUser(UserRequest) returns (UserResponse). That file is the actual contract — a code generator turns it into client and server stubs in whatever languages the services are written in, so calling a remote service looks almost identical to calling a local function. The payload is Protocol Buffers, a compact binary format that’s smaller and faster to parse than JSON but not readable without decoding it first.

Wire format and performance

REST typically runs over HTTP/1.1 or HTTP/2 with JSON bodies — verbose but universally supported and easy to inspect with a browser or curl. gRPC requires HTTP/2 and uses binary Protocol Buffers, which are smaller on the wire and faster to serialize and deserialize. For high-throughput, latency-sensitive internal traffic — one microservice calling another thousands of times a second — that difference in encoding overhead adds up. For a handful of requests a user makes from a browser, it rarely matters.

Streaming

This is one of the sharpest differences. REST is fundamentally request-response: one request, one response, and anything resembling a live stream has to be bolted on with something like Server-Sent Events or a WebSocket. gRPC, because it’s built on HTTP/2’s multiplexed streams, supports four call patterns natively: unary (one request, one response, like REST), server streaming (one request, a stream of responses), client streaming (a stream of requests, one response), and full bidirectional streaming. If your service needs to push a continuous feed of updates back to a caller — telemetry, live pricing, progress on a long-running job — gRPC’s streaming support is built into the protocol rather than layered on top of it.

The browser problem

Browsers can’t speak raw gRPC. JavaScript’s fetch and XMLHttpRequest don’t give you the low-level control over HTTP/2 trailers that gRPC needs, so calling a gRPC service directly from client-side code isn’t possible without an intermediary — typically a gRPC-Web proxy that translates between a browser-friendly protocol and native gRPC on the backend. REST has no such problem; any browser has spoken HTTP and parsed JSON since forever. This alone rules gRPC out for public-facing browser APIs and keeps it mostly confined to server-to-server traffic.

Comparison table

RESTgRPC
Data formatJSON (text)Protocol Buffers (binary)
TransportHTTP/1.1 or HTTP/2HTTP/2 only
ContractInformal, often OpenAPIStrict .proto schema, code-generated
StreamingNot native — needs SSE or WebSocketsNative, in all four directions
Browser supportNativeRequires a gRPC-Web proxy
Human readabilityHigh — plain JSONLow — binary, needs decoding
Best forPublic APIs, browser clientsInternal microservices, polyglot backends

Where this leaves GraphQL

There’s a third option worth knowing about: GraphQL, which lets clients specify exactly which fields they want in a single request instead of hitting fixed REST endpoints. GraphQL solves a different problem than gRPC does — over-fetching and under-fetching of data for client-driven queries — and the two aren’t really in competition. It’s common to see gRPC used between internal services and REST or GraphQL exposed at the edge for external clients, often behind an API gateway that translates between the two.

When to reach for which

Pick REST when you’re building a public API, serving browser clients directly, or want an API anyone can explore with minimal tooling. Its ubiquity is the real advantage — every language, every platform, and every developer already knows how to talk to it.

Pick gRPC when you control both ends of the connection, typically inside a microservices architecture where dozens of internal services call each other constantly, in different languages, and the overhead of parsing JSON and the lack of a strict typed contract start to cost real latency and bugs. The code generation from .proto files also means client and server can’t silently drift out of sync the way a REST API and its documentation sometimes do.

Many production systems use both: gRPC for the internal service mesh, REST (or GraphQL) at the boundary where external clients and browsers connect in.

The takeaway

REST and gRPC solve the same broad problem — letting one program call another over a network — with different tradeoffs. REST trades some performance for universal compatibility and human readability; gRPC trades that readability and easy browser access for speed, native streaming, and a contract that’s enforced by tooling rather than convention. The choice usually comes down to who’s calling the API: the open internet favors REST, a fleet of internal services you control favors gRPC.

Takina Takina · · 4 min read

REST vs GraphQL: Choosing an API Style

REST exposes fixed endpoints per resource; GraphQL lets clients query exactly the fields they need through one endpoint. How to choose between them.

#API #Web Development #Backend
Takina Takina · · 4 min read

What Is the Backend-for-Frontend (BFF) Pattern?

A backend-for-frontend (BFF) is a dedicated backend layer for one client type — shaping, aggregating, and simplifying calls to shared downstream APIs.

#Backend #Web Development #Architecture
The Lycoris Team The Lycoris Team · · 4 min read

API Versioning Strategies Explained

URI paths, custom headers, and content negotiation are the three common ways to version an API. Tradeoffs of each, and how to avoid breaking clients.

#Web Development #Developer Tools #Backend