Backend / Protocols / 00_api_protocols_comparison.md

API Protocols Comparison — REST, GraphQL, gRPC, SOAP

Updated 6 interview angles 5 min read source
On this page10
  1. The headline differences
  2. When to pick which
  3. Performance
  4. Schema and contract
  5. Wire format
  6. How errors work
  7. Client-server fit
  8. Combine them
  9. Related
  10. Interview angle

API Protocols Comparison — REST, GraphQL, gRPC, SOAP

Four ways to expose APIs. Different eras, different trade-offs. Interviewers commonly ask “when would you pick which?” — knowing what each is good and bad at is more important than knowing every detail.

The headline differences

REST GraphQL gRPC
Year 2000 (Fielding) 2015 (Facebook) 2015 (Google)
Transport HTTP/1.1 or HTTP/2 HTTP (usually POST) HTTP/2
Payload JSON (usually) JSON Protobuf (binary)
Schema OpenAPI (optional) SDL (built-in) .proto (built-in)
Typing weak unless OpenAPI strong strong
Browser-native yes yes no (needs gRPC-Web)
Streaming SSE / WebSocket on top subscriptions first-class (4 modes)
Versioning URL or header additive evolution proto evolution
Discoverability OpenAPI/Swagger introspection reflection (optional)
Error model HTTP status codes always 200 + errors array gRPC status codes
Caching HTTP cache (great) bespoke bespoke
Tooling universal rich (Apollo, Relay) rich (.proto codegen)

SOAP (1998, Microsoft), for comparison: XML over HTTP (also SMTP and TCP), a built-in and strongly typed WSDL schema, browser-capable but heavy, no streaming, WSDL for versioning and discovery, SOAP Fault for errors, bespoke caching, and dated but mature tooling.

When to pick which

REST — the default for public-facing HTTP APIs. Universal client support, HTTP caching, easy to understand. The right answer for ~80% of new B2B APIs.

GraphQL — when clients need flexible, varied views of the same data and over-fetching/under-fetching is costing you. Mobile apps with heterogeneous screens; aggregator UIs that combine many services. Cost: server complexity, N+1 risk, weaker HTTP caching.

gRPC — for service-to-service APIs in a controlled environment (microservices inside your VPC, or trusted partners). Tight schemas, fast binary protocol, streaming. Cost: not browser-native, less human-readable for debugging.

SOAP — only when you’re integrating with a system that requires it (legacy enterprise, banking, government). Don’t choose SOAP for new APIs. Use Zeep on the Python side to consume it.

Performance

Measured on a 20-item order message (Python 3.14, details in RPC and gRPC): Protobuf is about 3x smaller than JSON and about 10x faster than the standard json module, but under 2-3x faster than orjson and only 1.5x smaller once both are gzipped. All of it is microseconds per message.

text
GraphQL  ≈ REST per request, fewer round trips for complex queries
SOAP     slower than REST: XML parsing and envelope overhead

But network and database usually dominate. The protocol choice rarely is the bottleneck for typical CRUD APIs.

Schema and contract

Contract source Typed clients
REST OpenAPI / hand-written generate from OpenAPI
GraphQL SDL (schema.graphql) generate from SDL
gRPC .proto file generate from .proto
SOAP WSDL generate from WSDL

For all four, the schema is the contract. The difference is how “real” the schema is to the protocol: GraphQL/gRPC/SOAP enforce it at the wire level; REST + OpenAPI is contract-by-convention (the server can violate the OpenAPI doc without the framework noticing).

Wire format

A “get user” response in each:

REST (JSON):

json
{"id": 42, "name": "Alice", "email": "alice@example.com"}

GraphQL (JSON, but client decides shape):

json
{"data": {"user": {"name": "Alice"}}}

gRPC (Protobuf binary):

text
0x08 0x2a 0x12 0x05 0x41 0x6c 0x69 0x63 0x65 ...

SOAP (XML):

xml
<soap:Envelope>
  <soap:Body>
    <GetUserResponse xmlns="...">
      <User><Id>42</Id><Name>Alice</Name></User>
    </GetUserResponse>
  </soap:Body>
</soap:Envelope>

JSON is the universal denominator. Protobuf is fastest. XML is verbose. GraphQL’s payloads are JSON but request-shaped.

How errors work

REST: HTTP status code + JSON body. Convention: 4xx for client errors, 5xx for server. RFC 7807 (Problem Details) standardizes the body shape.

GraphQL: HTTP 200 even on errors. errors array in response. Partial data possible ({"data": {...partial...}, "errors": [...]}).

gRPC: status codes (OK, NOT_FOUND, INVALID_ARGUMENT, etc.) — 17 codes, OK (0) to UNAUTHENTICATED (16), returned in HTTP/2 trailers.

SOAP: <soap:Fault> element in the response body. HTTP 500 typically.

Client-server fit

Client Best fit Poor or only OK
Browser (JS) REST, GraphQL gRPC (needs gRPC-Web), SOAP (heavy)
Mobile (iOS/Android) REST, GraphQL, gRPC SOAP is only OK
Server-to-server gRPC (best), REST GraphQL and SOAP are OK
CLI REST SOAP is poor; GraphQL, gRPC OK
Embedded / IoT gRPC GraphQL, SOAP poor; REST OK

Browsers can do GraphQL natively (it’s HTTP+JSON), need a proxy/transcoding layer for gRPC, and chew through SOAP at significant cost. For browser-facing APIs: REST or GraphQL.

Combine them

It’s common to mix:

  • REST at the edge, gRPC internally: clients talk REST/JSON; backend microservices talk gRPC.
  • GraphQL gateway in front of REST/gRPC backends: clients get GraphQL flexibility; services stay simple.
  • SOAP adapter to a modern API: wrap a legacy SOAP system behind a REST or GraphQL facade.

The “best protocol” debate is mostly moot — modern stacks use each where it fits.

Interview angle 6

  • “REST vs GraphQL — when each?” — REST for simple resource-shaped APIs, public-facing, where HTTP caching matters. GraphQL when clients have heterogeneous data needs (mobile + web + partner integrations all hitting the same backend with different views) and over-fetching is real.
  • “REST vs gRPC?” — REST for browser-facing or public-partner APIs (HTTP/JSON, universal). gRPC for service-to-service in a controlled env: binary, streaming, schema-enforced, deadlines; faster per message, though the network usually dominates.
  • “When would you still use SOAP?” — only when a system you must integrate with requires it (banking, legacy enterprise, government). Don’t choose SOAP for new APIs.
  • “GraphQL vs gRPC — both have schemas, both are typed; what’s the diff?” — GraphQL is client-driven query shape over JSON; gRPC is fixed RPC over binary. GraphQL is for flexible read-mostly APIs; gRPC is for fast service-to-service calls with stable interfaces.
  • “Why doesn’t GraphQL cache as well as REST?” — REST URLs are cache keys; GET on /users/42 is cacheable in any HTTP cache. GraphQL almost always uses POST with query in body — same URL for every query, no cache key. You can do persisted queries with GET to recover HTTP caching, but it’s not the default.
  • “How do errors differ between REST and GraphQL?” — REST uses HTTP status codes (4xx/5xx). GraphQL almost always returns 200 with errors array, optionally with partial data. The “always 200” model lets multi-resource queries succeed for some fields while failing others.