7 lessons

API Styles

REST, RPC, gRPC and GraphQL as tools with prices, not religions. What each buys, what each costs operationally, and how consumer environment decides — never “which one is best”.

RequirementConsumersResource ModelStyleContractValidationAuthorizationErrorsIdempotencyPaginationVersioningObservabilityEvolutionTrade-offs

Every lesson below names the consumers, the design question and the guarantee before recommending anything. Recommendations come with what they cost, when not to use them, and how they evolve.

Which API Style Should I Use?

REST, RPC/gRPC, GraphQL, SSE, WebSockets, webhooks, async jobs — seven shapes, each answering a different question about who the consumer is and how data needs to move. The decision is made by consumer environment and operational budget, not by fashion.

Q · Given who consumes this API, where they run, and how data needs to flow, which contract shape fits — and what does that shape commit the team to operating?
REST as a Practical Style

REST is a set of constraints — addressable resources, uniform methods, representations, statelessness, cacheability — that let the whole HTTP ecosystem work for you unmodified. It is not "CRUD over HTTP", and its value is in the guarantees, not the URL aesthetics.

Q · What does designing "RESTfully" actually buy a consumer — and which of the constraints are worth keeping when the domain pushes back?
The "REST Purity" Anti-Pattern

Contorting every operation into one interpretation of REST hides domain semantics behind status flips and produces contracts nobody can read. Clarity and domain meaning outrank purity — and so does the opposite ditch, where "REST is limiting" excuses a verb for everything.

Q · When the domain pushes back against the resource model, do you bend the domain or bend the style — and how do you tell a principled exception from a lazy one?
RPC: Operation-Oriented Contracts

RPC contracts are lists of operations — `UserService.GetUser`, `InventoryService.ReserveInventory` — rather than resources with methods. When the domain is a set of commands between services, that is clearer than bending them into nouns; it costs caching, discoverability and verb discipline.

Q · When is "call this operation with these arguments" a clearer contract than "act on this resource with this method" — and what does the operation-shaped style give up?
gRPC: Schema, Codegen and Streams

gRPC is RPC with a schema language (protobuf), generated clients, binary framing and four call shapes including streaming, on HTTP/2. It buys enforced contracts and efficient internal traffic; it costs browser friendliness, readability, and a proto discipline that decides whether evolution is safe.

Q · What does a schema-enforced, binary, streaming RPC contract buy internal consumers — and what does it commit the team to when browsers, partners and evolution show up?
GraphQL: Client-Shaped Queries Over One Schema

GraphQL replaces many endpoints with one typed schema that clients query for exactly the fields they need: queries, mutations, subscriptions, resolvers behind each field. The benefits — no over/under-fetching, one contract for many client shapes, introspection — are real; so are the costs, which get their own lesson.

Q · When many clients need different slices of one connected data graph, what does letting the client choose the shape buy — and what does the server take on to make that safe?
What GraphQL Costs
▶ lab

The flexibility GraphQL gives clients is exposure the server must manage: resolver N+1, arbitrary expensive queries, per-field authorization, lost HTTP caching, invisible operations. Batching, cost limits, persisted queries and operation-level telemetry are the price — budget it before adopting the schema.

Q · Who bounds the cost of a query you never anticipated — the schema, the resolvers, or the outage — and what machinery moves that answer from "outage" to "schema"?