🧭 Analogy
Choosing an API style is like choosing how to send a parcel. A standardised postal service (REST) is universal and works for strangers, but it is verbose and a little slow. A dedicated courier on a fixed route between two warehouses you own (gRPC) is fast and efficient. A personal-shopper service that fetches exactly the items you list from many shops in one trip (GraphQL) saves you sorting through everything yourself. None is “best” — each fits a different errand.
It is not REST versus gRPC
Mastering API Architecture hammers one point: the real architectural work is design and structure, not picking a winning protocol. You choose the most appropriate format for each exchange between a producer (owns the API) and a consumer (calls it), considering who they are and what they exchange. Most answers are “it depends” — record the decision in an ADR.
Two traffic directions drive the choice:
- North–south traffic — ingress from outside your ecosystem (a mobile app, an external partner). Usually high latency, loosely coupled, security-critical.
- East–west traffic — internal service-to-service calls. One north–south request often triggers many east–west exchanges, so east–west efficiency compounds.
graph TD C["External consumer<br/>(mobile app, partner)"] -->|"north-south<br/>REST / GraphQL"| GW["API Gateway"] GW --> A["Attendee service"] A -->|"east-west<br/>gRPC"| S["Session service"] A -->|"east-west<br/>gRPC"| B["Booking service"]
REST — loose coupling, stateless, a domain model
REST (Representational State Transfer) is a set of architectural constraints, usually over HTTP. To be RESTful an API must model resources, be stateless (the consumer sends all context each request), be cacheable, present a uniform interface (verbs + resources), and be a layered system that hides the backing implementation. Because REST projects a domain model rather than exact functions, it favours loose coupling — ideal for external consumers you cannot coordinate with easily, like a third-party Call-for-Papers system. The trade-off is verbosity (JSON inflates payloads) and chattiness. See REST and the Richardson Maturity Model.
RPC and gRPC — fast, schema-driven, potentially coupled
RPC (Remote Procedure Call) exposes a method in one process to be called from another, rather than projecting an abstraction. gRPC is the de facto modern RPC framework: it requires a .proto schema, uses a client-side stub, runs on HTTP/2 with a binary protocol, and multiplexes many requests over one connection. This makes it excellent for high-traffic east–west exchanges and large payloads.
HTTP/2 multiplexing
Under HTTP/1, 20 attendee requests meant 20 TCP connections. Under HTTP/2, all 20 ride a single connection through a transparent binary framing layer that splits and compresses messages — a major win when bandwidth or transfer cost is the concern.
gRPC is far stricter than REST. Field numbers govern wire layout, so removing, renaming, retyping, or renumbering a field is a breaking change; you may only add a service, method, or non-mandatory field safely. RPC can also build up state and is potentially more coupled — but coupling is not always bad for two services you control.
graph TD
Q{"What is the exchange?"} -->|"external, loose coupling"| REST["REST"]
Q -->|"internal, high traffic, performance"| GRPC["gRPC"]
Q -->|"precise fields across many APIs"| GQL["GraphQL"]
REST --> NS["north-south ingress"]
GRPC --> EW["east-west service to service"]
GQL --> UI["mobile, UI, reporting"]GraphQL — precise queries across many APIs
GraphQL is a technology layer over existing services and datastores that gives clients a query language to request exactly the fields they need, including fields that span multiple APIs, behind a single schema and version. It removes consumer-side version juggling and shines for mobile (small screens, constrained networks), UI modelling, and reporting/data-warehouse access over many interconnected services. It can act as a facade over legacy systems, and is simplest when layered over already well-designed APIs.
Can one service offer all three?
Yes — but it is usually the wrong thing to do. Tools like openapi2proto reorder fields alphabetically (silently breaking gRPC compatibility), and grpc-gateway makes RPC pretend to be REST. Conflating an extended hypermedia domain model with low-level function calls makes versioning painful.
Pitfall: the 'golden specification'
Once you generate one specification from another (REST↔gRPC), versioning becomes hard and every change ripples. The book’s recommendation, recorded as an ADR: design the RPC (east–west) and REST (north–south) representations independently so each can evolve freely.
See also
- Designing good APIs — API-as-a-product and consumer-first design.
- REST and the Richardson Maturity Model — how RESTful an API really is.
- Messaging styles and patterns — when synchronous request/response is the wrong tool entirely.
When to use it — and when not
✅ Reach for it when
- You are starting a new out-of-process API and must pick an interaction style.
- You need to justify a style choice to other teams in an ADR.
- You are weighing loose coupling against raw performance for a given call.
⛔ Think twice when
- The interaction is in-process (a method call inside one process) — these trade-offs do not apply.
- An organisation-wide mandate or platform already fixes the style for you.
Related topics
Design from the consumer's perspective, adopt a standard early, and treat the API as a long-lived product — because the API is the contract.
api-restREST and the Richardson Maturity ModelREST's constraints and the four levels of the Richardson Maturity Model — and why Level 2 is the practical sweet spot for most HTTP APIs.
api-messagingMessaging Styles and PatternsBeyond synchronous request/response: be message-centric, use shared vocabularies, and coordinate work via orchestration, choreography, or hypermedia workflow.
Check your understanding
Score: 0 / 41. According to Mastering API Architecture, what is the right framing for choosing an API style?
The book's recurring theme is that the real work is design and structure; you choose the format per exchange, weighing coupling, traffic and payload.
2. Which style is best suited to high-traffic, east–west service-to-service calls where performance matters?
gRPC uses HTTP/2 and a binary protocol with full multiplexing over one connection — ideal when bandwidth/cost matter and callers are two producer-controlled services.
3. What problem does GraphQL primarily solve?
GraphQL is a query layer over existing services giving clients precise field selection across APIs with a single version — strong for mobile, UIs and reporting.
4. Why is coupling not always a bad thing when choosing RPC?
RPC conveys exact method-level functionality and can be more coupled; that is acceptable for east–west services you control where high performance is the priority.
Comments
Sign in with GitHub to join the discussion.