Module 04 · API fundamentals · Lesson 2 of 15
API styles: REST, GraphQL, gRPC and the rest
Four ways to shape an API: resource-oriented REST, query-shaped GraphQL, procedure-shaped gRPC and event-shaped async messaging. What each optimises for, where each is the wrong tool, and the usual pairing in a real system.
Why it matters
The style of an API decides who finds it easy: the browser developer who wants exactly the fields a screen needs, the backend engineer who wants fast typed calls between services, the partner who wants to be told when something happens. Picking one style for everything forces at least one of those people to fight the tool. Most mature systems use two or three styles, each where it fits, and the interview question is whether you know which is which.
The idea
An API style is a convention for how operations, data and errors are expressed over a transport. Four cover nearly everything.
REST models the world as resources addressed by URLs and manipulated with HTTP methods. GET /orders/42 reads an order, POST /orders creates one. It leans on HTTP's caching, status codes and ubiquity; any client that speaks HTTP can use it. Its weakness is shape: a screen that needs an order, its customer and its items makes three requests or gets one bloated response.
GraphQL exposes a typed schema and lets the client ask for exactly the fields it wants, across related objects, in one request. It solves REST's over- and under-fetching and gives front-end teams independence. It costs server complexity (query cost analysis, N+1 query problems, caching that HTTP no longer does for you).
gRPC is remote procedure calls with protocol buffers over HTTP/2: strongly typed, compact, fast, with generated clients in every language and native streaming. It is the default for service-to-service calls inside a system. Browsers cannot speak it directly, and payloads are not human-readable.
Asynchronous messaging (webhooks, queues, event streams) is not request-response at all: the provider emits events and consumers react later. It decouples producers from consumers and absorbs bursts; it also gives up the simple "call and get an answer" model, which the Communication patterns module covers.
| REST | GraphQL | gRPC | Async events | |
|---|---|---|---|---|
| Shape | Resources and HTTP methods | Client-specified queries over a typed graph | Typed procedures, binary messages | Events published to subscribers |
| Best for | Public APIs, CRUD, anything cacheable | Rich client UIs with varied data needs | Service-to-service, high throughput, streaming | Notifications, decoupling, bursty work |
| Caching | HTTP caching works out of the box | Per-field, client-side; HTTP caching mostly lost | Application-level only | Not applicable |
| Typing | Optional (OpenAPI) | Required (schema) | Required (protobuf) | Schema registry recommended |
| Browser support | Native | Native (over HTTP POST) | Needs a proxy (gRPC-Web) | Via WebSockets or SSE |
| Main cost | Over/under-fetching, many round trips | Server complexity, query cost control | Not human-readable, browser gap | Eventual consistency, harder debugging |
How to choose
Ask who the caller is and what they struggle with. Many different clients with different screens: GraphQL at the edge. Third parties and anything that should be cacheable and discoverable: REST. Your own services talking to each other at volume: gRPC. Anything that is a reaction to something happening rather than a question: events. Mixing styles is normal; exposing all of them to every caller is not.
Trade-offs
Each style trades flexibility, performance and simplicity differently, and adding a style adds a toolchain, a set of conventions and a learning curve for the team. A small system is usually best served by REST alone; the signal to add GraphQL is front-end teams building bespoke aggregation endpoints, and the signal to add gRPC is service-to-service latency or payload size that matters.
In an interview
State the pairing and the reason: "REST at the public edge because partners expect it and responses cache well; gRPC between services for typed, fast calls; order events on a queue so shipping and email react without coupling to checkout." If the interviewer suggests GraphQL, give the honest condition: "Worth it once several client teams need different slices of the same graph; before that it is overhead."
Check yourself
A mobile team complains that rendering the home screen takes seven REST calls and still returns fields they never use. Which style addresses this most directly?