Web API Architectural Styles — Overview

REST, GraphQL, gRPC, SOAP, WebSocket, webhook. The catalogue, when each is right, and why every team thinks theirs is special.

Concept Foundational
9 min read
api architectural-style rest graphql grpc

Summary#

Pick any large engineering org and you will find at least three API styles wired into production. The public partner surface is REST. The mobile clients hit a GraphQL gateway. The internal mesh is gRPC. The chat product runs WebSocket. The billing webhook ships POSTs to merchant URLs. The legacy core that nobody has rewritten yet still speaks SOAP.

There is no universal winner among API styles. There is a catalogue of six options, each shaped by what its inventors were optimising for at the time, and a body of accumulated practice for matching style to consumer. The senior signal in an API-design interview is naming the styles, knowing what each is good for, and picking deliberately — not parroting whichever one was on the front of Hacker News last week.

This page is the catalogue. Six styles, one paragraph each, then a decision table.

Why it matters#

Three reasons the choice of style is the first decision in any API design, and the hardest to undo:

  • The style picks your tooling for the next five years. Choose REST and you inherit OpenAPI, Postman, every HTTP library, every CDN. Choose gRPC and you inherit Protobuf compilers, BloomRPC, codegen pipelines, but you give up curl-from-the-terminal debuggability. The choice is sticky because the tooling investment is sticky.
  • The style leaks into the consumer’s code. A REST client looks like requests.get(url). A GraphQL client looks like a query string and a schema-aware library. A gRPC client looks like a generated stub with strongly-typed methods. The integrator’s developer experience is your style choice in compiled form.
  • The wrong style is hard to walk back. Migrating a public API from REST to GraphQL is a multi-year project with deprecation timelines and dual-stack support. Migrating an internal service from gRPC to REST is easier but still expensive. Pick the style once, on day one, with the right consumer in mind.

The interview question “REST or GraphQL or gRPC?” is rarely literal. The interviewer wants to hear the decision process — not the answer.

How it works#

There are six API styles worth knowing. Each evolved out of a specific pain the previous generation could not handle.

REST — resources over HTTP#

REST is an architectural style (not a protocol) defined by Roy Fielding’s 2000 PhD thesis. It says: model your domain as resources, identify each resource by a URI, manipulate them through a uniform set of verbs (GET, POST, PUT, PATCH, DELETE), and keep the server stateless between requests. In practice, “REST” almost always means REST-ish JSON over HTTP — the strict HATEOAS form is rare.

REST won the public-Internet API category. Stripe, GitHub (v3), Twilio, AWS (most services), every SaaS with a partner API — REST. The reasons are mundane and powerful: every language has an HTTP client, every browser speaks HTTP natively, every proxy and CDN understands HTTP semantics, every dev can curl an endpoint to debug it. The ecosystem is the moat.

GraphQL — a query language for APIs#

GraphQL, originally from Facebook (2012, open-sourced 2015), is a query language that lets the client describe exactly which fields it wants from a resource graph. One endpoint (POST /graphql) accepts a query like { user(id: "1") { name, orders(last: 5) { total } } } and returns exactly those fields. The schema (defined in SDL, the Schema Definition Language) is the contract; introspection lets clients discover the schema at runtime.

GraphQL exists because REST over-fetches and under-fetches on rich client UIs. A mobile screen that needs the user’s name, their last five orders, and the total of each would need three REST calls (or one fat call that ships every field of each object). GraphQL collapses it into one query that returns one response shaped exactly to the screen. The cost is the new complexity it introduces: server-side N+1 queries, authorization at the field level, query-cost analysis, and a fundamentally different tooling story.

gRPC — Protobuf RPC over HTTP/2#

gRPC is an RPC framework open-sourced by Google in 2015. The service is defined in Protobuf (a binary IDL), the transport is HTTP/2, and the client-server contract compiles to strongly-typed clients in 10+ languages. Four streaming modes are supported: unary (one request, one response), server-streaming, client-streaming, and bidirectional.

gRPC’s home is the internal polyglot mesh. Where REST is verbose for service-to-service calls (encoding a function call as a verb on a resource is ceremony) and JSON is wasteful for high-throughput internal traffic, gRPC’s binary framing and codegen story make client.GetUser(req) look like an in-process call. Google, Netflix, Square, Cloudflare, every modern fintech with a polyglot backend — gRPC. The browser story is gRPC’s weakest point (browsers cannot speak raw HTTP/2 frames; you need grpc-web with a translating proxy), which is why public APIs over gRPC remain rare.

SOAP — the XML elder#

SOAP (Simple Object Access Protocol) is a 1998-vintage XML-based RPC protocol with a heavy ecosystem of WS-* specs (WS-Security, WS-Trust, WS-ReliableMessaging, WS-AtomicTransaction). A SOAP service publishes a WSDL document; clients consume the WSDL and generate a strongly-typed stub.

SOAP is legacy in the polite sense: it’s still everywhere in banking, insurance, government, and large enterprise integration, and it’s not getting greenfield investment. If you’re integrating with an SAP backend, a Salesforce SOAP endpoint, or a 2005-era bank API, you’ll write SOAP. For a new API in 2026, you almost certainly should not pick SOAP.

WebSocket — bidirectional streaming#

WebSocket (RFC 6455, 2011) upgrades an HTTP connection to a full-duplex bidirectional channel. After the handshake, both sides can send messages at any time over a single TCP connection. The framing is binary or text; the application protocol on top is whatever you build.

WebSocket fits real-time interactive surfaces: chat (Slack, Discord), collaborative editing (Figma, Google Docs), live trading dashboards, multiplayer games, notification streams. It is not a request-response style — modelling CRUD over WebSocket is awkward. It is also stateful (every connection is a long-lived resource the server must track), which complicates horizontal scaling.

Webhook — server-pushed events#

Webhook is an HTTP POST that your service sends to a customer-supplied URL when an event happens. Stripe webhooks fire when a payment succeeds or fails. GitHub webhooks fire when someone opens a pull request. Slack webhooks fire when a slash command is invoked.

Webhooks invert the usual client-server direction: your service becomes the client of someone else’s HTTP server. The delivery semantics are at-least-once with retries, signatures (HMAC-SHA256) to authenticate the sender, and the consumer is responsible for idempotency. Webhooks are not really a separate style so much as a delivery pattern layered on top of HTTP — but the design surface is distinct enough (event taxonomy, retry policy, signing, replay) that it earns its own row in the catalogue.

Variants and trade-offs#

The right style depends on who’s calling and what they’re doing. The table below is the cheat sheet — when a candidate produces it from memory in an interview, the interviewer knows they’ve thought about this before.

ConsumerOperation shapeRecommended styleWhy
Public partner backendResource CRUDRESTTooling, cacheability, browser-friendly
Internal microservice (polyglot)RPC calls, high QPSgRPCCodegen, binary framing, HTTP/2 multiplexing
Mobile appRich nested reads, screen-shapedGraphQLOne query per screen, no over/under-fetch
Browser SPAMixed reads and writesREST or GraphQLBoth work; GraphQL wins on complex screens
Real-time UIBidirectional streamingWebSocketFull-duplex, low-latency
Server-to-server eventsAsync notificationWebhookAt-least-once delivery, signed
Legacy enterprise integrationXML-RPC, WS-*SOAPWhat the other side speaks
AI agent invoking your serviceTool callsREST (typically)What every model-provider tooling understands today

A second axis: what part of the design is most expensive to get wrong changes by style.

REST and GraphQL — the expensive mistake is the schema. Once a public REST endpoint exists, every breaking change is a deprecation timeline. GraphQL is the same: removing a field is a public commitment, not a refactor.

gRPC — the expensive mistake is the Protobuf field numbering. Renumbering a field is a wire-incompatible change. Reserved field numbers and reserved directives exist for exactly this reason. The schema is permanent.

When this is asked in interviews#

The opening question of an API-design interview is rarely “design an API.” It is more often “what style would you pick, and why?” — sometimes phrased as “REST or GraphQL for this?” The interviewer is watching whether you:

  • Clarify the consumer first. Browser, mobile, internal? Public, partner, internal? The audience determines the style. A senior candidate asks before answering.
  • Avoid dogma. “We always use REST” or “GraphQL is always better” is a junior signal. The senior signal is “for this consumer, REST because [reasons]; if the consumer were [different], I’d pick [different style].”
  • Name the cost of the choice. Picking gRPC costs you browser support and curl-debuggability. Picking GraphQL costs you cacheability and adds N+1 risk. Naming the cost shows you’ve actually shipped one of these.
  • Know when to mix. Many production architectures are REST on the edge, gRPC internally, GraphQL for mobile, WebSocket for real-time. Mixing styles per surface is mature. Trying to force one style everywhere is the rookie move.
  • Handle the SOAP question gracefully. If the interviewer mentions SOAP, the right answer is “I’d avoid it for greenfield; if I have to integrate with an existing SOAP system, I’d write an adapter layer.” Don’t bash it; don’t pick it.

The one-line summary to leave the interviewer with: “There is no universal winner. The style is a function of the consumer.”

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.