REST, GraphQL, gRPC, and tRPC are not just protocol choices. They are political choices between teams. Here is when each one works best, and when it will fight you.
When you scale from a handful of backend services to a network of teams shipping independently, you discover something quickly: APIs are politics. Distributed systems are rarely brought down by storage engines or consensus protocols. More often, teams trip over something far more mundane: how services talk to each other.
Every endpoint, response code, and contract revision is a small treaty between teams.
Over the past two decades, we’ve accumulated a surprising number of “languages” for machines to negotiate with. Each emerged for a reason, solved a pain, and introduced new ones. Below is a practical, engineer-first view of how these protocols evolved, where they shine, and where they are the wrong tool.
Thanks for reading Olko - Tech/Engineering! Subscribe for free to receive new posts and support my work.
Thanks for reading oleg’s Substack! Subscribe for free to receive new posts and support my work.
1. HTTP: The Common Language We Still Rely On
HTTP/1.1 remains the most widely adopted communication layer in distributed systems.
It works because it is:
simple
predictable
well-understood
universally supported
It gave us a shared vocabulary:
GET – retrieve
POST – create
PUT – replace
DELETE – remove
And a tone of voice through status codes:
200 : all good
404 : not here
500 : your server caught fire
Despite its age, HTTP continues to be the stable foundation on which everything else is built. You can replace frameworks. You cannot replace HTTP.
2. REST: When APIs Became Civilized
REST was not created to be “yet another API style.”
It was created to impose order.
Roy Fielding’s dissertation argued that networked systems should revolve around resources (nouns), not verbs:
GET /orders/123
POST /users
DELETE /sessions/42
REST gave teams:
statelessness
predictable semantics
cacheability
standardization
This model worked exceptionally well for public APIs and internal boundaries where stability mattered more than speed or flexibility.
The biggest complaint? Overfetching.
REST returns the full representation of a resource, even when the client wants two fields.
Where REST is a good fit
Example: Stripe / GitHub style public APIs.
Example: Internal “platform” APIs between teams.
Where REST is usually the wrong tool
Your mobile app makes 6–8 REST calls to render a single screen, overfetching large payloads. Latency and data usage are now a product problem.
Your frontend needs to assemble data from 4–5 services per view. You start building ad-hoc “backend for frontend” aggregation endpoints to paper over REST limitations. At this point, GraphQL is often a better abstraction.
3. SOAP, RMI, CORBA: The Empires That Collapsed
Before REST, enterprise engineering tried RPC over heavy, rigid contracts:
RMI
CORBA
SOAP
They assumed distributed systems should behave like local function calls.
It looked nice on whiteboards and failed in practice:
systems tightly coupled across languages and vendors
brittle XML contracts
versioning nightmares
huge payloads
These approaches taught the industry one important lesson:
When your service boundary looks like a shared class, you’re building a distributed monolith.
Where SOAP still makes sense
- Example: Legacy payment, insurance, telecom backends.
Where SOAP is the worst option
- Greenfield product, 2025, building a public API for a web and mobile client. Choosing SOAP here is self-sabotage. REST, GraphQL, or gRPC will all be strictly better in tooling, performance, and developer experience.
4. GraphQL: The Negotiator
Facebook developed GraphQL because frontend teams were tired of REST returning massive payloads.
GraphQL flipped the contract upside down:
The client chooses the shape of the data.
The server must comply.
Example:
query {
shipment(id: 42) {
origin
destination
fuelUsed
}
}
Benefits:
precise data retrieval
strong types
single endpoint
Costs:
complex caching rules
backend resolvers easily turn into N+1 factories
schema ownership shifts toward frontend teams
more infra and operational overhead
GraphQL is great when UI teams outnumber backend teams and iteration speed matters more than backend control.
Where GraphQL is a good fit
Example: Shopify Storefront API / GitHub GraphQL API.
Example: Mobile apps under tight latency and bandwidth constraints.
Where GraphQL is the wrong tool
Internal service-to-service communication where:
Simple public APIs where you:
5. gRPC: The High-Performance Hotline
As systems grew, some teams needed:
speed
type safety
bi-directional streaming
efficiency over public accessibility
gRPC (Google’s modern RPC over HTTP/2) filled that gap.
Proto files define strict typed contracts:
service TradeService {
rpc InitiateTrade(TradeRequest) returns (TradeResponse);
}
Strengths:
binary, compact
extremely fast
codegen for many languages
great for internal service-to-service calls
Tradeoffs:
harder to debug over the wire
not ideal for random third-party clients
browser support requires gRPC-Web and extra infra
Where gRPC is a good fit
Example: Internal trading / risk / pricing microservices.
Example: ML inference and data pipelines.
Where gRPC is the wrong tool
Public APIs aimed at:
Browser-only clients without gRPC-Web. You will end up building HTTP/JSON shims anyway.
6. tRPC: The TypeScript Shortcut
Teams building full-stack TypeScript apps (Next.js, Node) realized something:
“Why maintain two schemas—one for backend, one for frontend—if both sides already use TypeScript?”
tRPC removed the boundary entirely:
no schema files
no codegen
types flow automatically through the stack
It works exceptionally well when:
the entire system is TypeScript-based
you control both sides of the API
you want fast iteration over long-term stability
Where tRPC is a good fit
Example: B2B SaaS admin / dashboard app.
Example: Internal tools and ops consoles.
Where tRPC is the wrong tool
You need a public API for third-party customers.
You expect to migrate parts of the stack to Go, Rust, or Java.
7. API Gateways: Bureaucracy That Scales
Once an organization has enough services, APIs need governance.
This is where API gateways and service meshes come in.
Gateways handle:
authentication
rate limits
versioning
routing
monitoring
Service meshes handle:
mTLS
retries
service discovery
request shaping
This structure turns chaotic service communication into enforceable policy.
Real-world patterns
Example: Public-facing platform API.
Worst case: “Gateway as dumping ground.”
8. When to Use What: A Practical Decision Table
9. The Real Lesson
APIs are not technology choices.
They are alignment choices.
The real job is ensuring that:
teams agree on contracts
versioning is respected
breaking changes are controlled
services remain independently deployable
communication remains predictable
Distributed systems fail on semantics long before they fail on transport.
The better the protocol, the easier the negotiation.
But the negotiation is unavoidable.
10. Final Thought
The industry keeps inventing new ways for machines to communicate.
REST will not die.
GraphQL will not replace REST.
gRPC will not replace GraphQL.
tRPC will not replace anything outside TypeScript ecosystems.
Each solves a different piece of the same problem:
How do we get independent systems—and teams—to understand each other well enough to ship?
In that sense, HTTP really is the diplomacy layer of modern software. Everything else is negotiation technique.
Thanks for reading oleg’s Substack! Subscribe for free to receive new posts and support my work.
Thanks for reading Olko - Tech/Engineering! Subscribe for free to receive new posts and support my work.


Top comments (0)