Chapter 09 · APIs

API Paradigms


REST, RPC, gRPC, GraphQL, event APIs, webhooks, and streaming interfaces optimize different dimensions. They can coexist in one architecture: REST-like HTTP at a public boundary, gRPC internally, GraphQL as a client aggregation layer, and events for asynchronous state propagation. Senior candidates compare semantics, tooling, coupling, schema evolution, caching, failure modes, and organizational fit.

Level: foundation → senior/staff Primary skill: selecting interaction and contract styles by workload rather than fashion Companions: HTTP · API Design · WebSockets · Message Queues

How to use this chapter

  1. Read the mental model and mechanics without taking notes.
  2. Close the page and explain the topic aloud in five minutes.
  3. Work the quantitative example on paper.
  4. Answer the question ladder without revealing the answer signals.
  5. Complete one design drill and score yourself with the senior checklist.

Learning objectives

  • Explain REST constraints and distinguish REST from generic JSON-over-HTTP.
  • Compare RPC/gRPC, GraphQL, event-driven APIs, webhooks, and streaming APIs.
  • Choose paradigms based on latency, coupling, client diversity, data shape, and evolution.
  • Design schema/version compatibility for request/response and event contracts.
  • Identify N+1, over/under-fetching, chatty calls, replay, and delivery-semantics risks.
  • Govern a polyglot API ecosystem at senior level.

Mental model

An API paradigm determines how clients express intent, how contracts are described, how data is transported, and where coupling appears. Resource-oriented HTTP exposes state through uniform semantics. RPC exposes operations. GraphQL lets the client select a typed response shape. Events announce facts to potentially many consumers. Streaming keeps an interaction open over time.

Core mechanics

REST and resource-oriented HTTP

REST is an architectural style with constraints including client-server separation, stateless interactions, cacheability, a uniform interface, layered systems, and optional code-on-demand. In practical interviews, focus on resource identifiers, representations, standard methods/status, links where useful, and cache/intermediary compatibility.

A JSON endpoint using POST for every action can still be a valid HTTP API, but it is not gaining much from the uniform interface. Resource APIs work well for public CRUD-like domains, cacheable reads, broad tooling, and evolvable representations.

RPC and gRPC

RPC models remote operations as method calls. gRPC commonly uses Protocol Buffers as an IDL and message format, generates clients/servers, and supports unary plus streaming calls. Strong typing and code generation improve internal developer productivity and compatibility discipline.

The method-call illusion is dangerous if it hides network failure, deadlines, retries, and partial execution. gRPC uses HTTP semantics over HTTP/2 in common deployments, but browser support, intermediaries, human inspectability, and public ecosystem compatibility may favor HTTP/JSON at external boundaries.

GraphQL

GraphQL exposes a typed schema through which clients request exactly selected fields and nested relationships. It is useful when many clients need different views and a graph gateway can aggregate domains. It reduces endpoint proliferation but does not automatically reduce backend work.

Resolver implementations must avoid N+1 calls through batching/data loaders, enforce depth/complexity/cost limits, and handle partial errors. Caching often occurs at object/resolver or persisted-query layers rather than generic URL caches. Schema deprecation enables gradual evolution, but removing fields still requires usage telemetry and client coordination.

Events and message contracts

Event APIs publish facts such as OrderPlaced or state-change notifications. Consumers can be decoupled in deployment and time, and producers need not know all subscribers. Events should have stable IDs, timestamps, schema versions, source, subject, and clear semantics.

Notification events may tell consumers to fetch current state; event-carried state transfer includes enough data to update local views. The latter reduces callbacks but duplicates data and increases privacy/schema concerns. Event sourcing is a stronger pattern where an event log is the source of truth; it should not be conflated with ordinary integration events.

Webhooks and callbacks

Webhooks are server-to-server HTTP callbacks triggered by events. Delivery is typically at least once, so receivers need idempotency and signature verification. Providers need retry schedules, expiry, disable policy, secret rotation, endpoint verification, and delivery logs.

Webhooks cross organizational boundaries and can become an SSRF vector. Restrict destination schemes/ports, resolve and validate addresses carefully, control redirects, and protect internal metadata networks. Provide replay and event query APIs because receivers will miss deliveries.

Streaming and subscriptions

Server streaming, bidirectional gRPC, WebSockets, SSE, and GraphQL subscriptions deliver values over time. They reduce polling and support low latency but introduce connection state, flow control, resume cursors, version skew, and load-balancer concerns.

A stream should define ordering scope, checkpoint/ack behavior, maximum lag, retention, and how schema changes affect long-lived clients. Often a snapshot API plus a delta stream is more robust than a stream alone.

Schema and compatibility

Backward-compatible evolution usually adds optional fields, new enum values handled safely, and new methods/resources. Removing or changing meaning is breaking even if wire parsing still succeeds. Consumers must ignore unknown fields where the format allows and avoid exhaustive assumptions about enums unless contracts require it.

For events, compatibility includes replaying old history into new code. Maintain schema registry/checks, examples, semantic documentation, and consumer-driven tests. Version at the smallest useful scope rather than cloning an entire API for one incompatible field.

Choosing a portfolio

Public, third-party APIs often favor HTTP/JSON plus OpenAPI because of universal tooling. Internal low-latency service calls may favor gRPC. Mobile/web aggregation can use GraphQL or backend-for-frontend APIs. State propagation and workflows use events/queues. The portfolio needs common identity, observability, deadlines, error taxonomy, ownership, and lifecycle policy.

Avoid forcing one paradigm everywhere. Standardize decision criteria and cross-cutting behavior, then permit exceptions with measurable reasons.

Decision table

DecisionPrefer the first option when…Prefer the second option when…Senior caveat
REST-like HTTP vs RPCPublic interoperability, cache semantics, and resource lifecycle dominate.Operation-centric domain, generated clients, and strong internal typing dominate.Both need explicit deadlines, idempotency, auth, and versioning; naming style does not determine scalability.
GraphQL vs purpose-built endpointsMany client types need flexible graph-shaped views and central schema governance exists.Stable use cases, simple caching, and predictable backend cost dominate.GraphQL gateway can become a policy/performance monolith; purpose-built BFFs can be simpler.
Event notification vs event-carried stateConsumers can fetch authoritative current state and callback volume is acceptable.Autonomous local views and reduced synchronous coupling matter.Carried data increases schema/privacy footprint and stale interpretation risk.
Webhook vs pollingLow-latency push and provider-controlled event delivery matter.Receiver cannot expose endpoint or simpler pull/reconciliation is preferred.Many systems offer both: webhook for promptness, polling for repair.
Unary vs streaming RPCRequests are independent and bounded.Continuous results, bidi interaction, or setup amortization matters.Streaming complicates load balancing, backpressure, retries, and version rollout.
One API style vs polyglotA small organization benefits from maximum consistency.Distinct boundaries have materially different needs.Standardize cross-cutting policies and ownership even when transport styles differ.

Quantitative reasoning

Failure modes and production signals

Failure modeWhat users seeLikely causeMitigation / design responseUseful signals
RPC retry duplicateRepeated side effectRemote-call illusion hides commit-after-timeoutIdempotency, deadlines, status lookup, retry classificationAttempt count, duplicate IDs, late responses
GraphQL resolver explosionGateway and dependencies overload on one queryN+1, deep/wide query, expensive fieldsBatch, cache, cost limits, persisted queries, timeoutsResolver count/time, downstream fan-out, query cost
Event schema breakConsumers fail or silently misinterpretRemoved field/changed meaning/new enum assumptionCompatibility checks, versioned semantics, replay tests, deprecationConsumer errors, schema-registry rejects, lag
Webhook stormProvider/receiver saturatedRetries without jitter/circuit or broad outagePer-endpoint backoff, caps, DLQ/replay, disable policyDelivery attempts, endpoint failure rate, queue age
Stale materialized viewAPI returns delayed/inconsistent dataEvent lag/replay failureExpose freshness, repair from source, prioritize lag, fallbackConsumer lag, last applied sequence, mismatch audits
Paradigm fragmentationClients face inconsistent auth/errors/versioningUnmanaged polyglot APIsShared governance/tooling, templates, lifecycle registryAPI inventory, policy violations, support tickets

Senior-level lenses

Choose by boundary

External clients, internal services, analytics pipelines, and browser live updates are different boundaries. State the user of the contract, trust domain, latency, compatibility horizon, and operational owner before selecting a paradigm.

Semantic coupling outlives transport

A protobuf field or event name can stay wire-compatible while its meaning changes and breaks consumers. Document invariants, units, null/absence, enum behavior, and lifecycle. Semantic review is as important as schema linting.

Aggregation moves cost

GraphQL/BFF endpoints reduce client calls but create server fan-out and caching challenges. Materialized views reduce read latency but add asynchronous lag and repair. Senior candidates identify where work moves and how it is bounded.

Async needs reconciliation

Webhooks and events should not be the sole way to discover truth. Provide cursors, list/status APIs, replay, snapshots, or periodic reconciliation so missed/duplicate/out-of-order delivery is repairable.

Generated clients are governance

IDLs/OpenAPI can generate code, but quality depends on naming, pagination, errors, deadlines, compatibility, and release policy. Generated clients also create version distribution problems; support old clients and track usage.

Cost limits are part of the API

Flexible queries and streams require quotas expressed in meaningful work units: resolver cost, returned bytes, subscriptions, messages, and fan-out. Simple request-per-second limits can be gamed by one expensive request.

Interview question ladder

Q9.1 foundation

REST versus RPC: what is the conceptual difference?

Show strong-answer signals

REST exposes resources through a uniform interface; RPC exposes operations/method calls. Avoid claiming one uses HTTP and the other does not.

Q9.2 foundation

What problem does GraphQL solve?

Show strong-answer signals

Client-selected typed response shapes and graph traversal for diverse clients; also mention resolver cost, caching, and governance.

Q9.3 foundation

What delivery semantics should a webhook consumer assume?

Show strong-answer signals

At least once in practice: duplicates, delays, reordering, expiry. Verify signature and make processing idempotent.

Q9.4 intermediate

When is gRPC a good choice?

Show strong-answer signals

Internal typed polyglot services, code generation, low overhead, streaming, deadline/cancellation support; discuss browser/proxy/public ecosystem constraints.

Q9.5 intermediate

How do you evolve an event schema safely?

Show strong-answer signals

Add optional fields/defaults, preserve meaning, tolerate unknowns, schema checks, version where incompatible, replay old history, usage/deprecation telemetry.

Q9.6 intermediate

What is the GraphQL N+1 problem?

Show strong-answer signals

Nested resolvers issue per-item backend calls. Use batching/data loaders, joins/read models, caching, and cost metrics.

Q9.7 senior

Choose API paradigms for a ride-sharing platform.

Show strong-answer signals

Public mobile BFF/GraphQL or HTTP; internal gRPC for low-latency services; events for trip state/analytics/notifications; WebSocket/SSE for live location. Justify boundaries and consistency.

Q9.8 senior

Design a reliable webhook product.

Show strong-answer signals

Subscription verification, signed events, stable IDs, ordering scope, at-least-once retries with jitter, endpoint caps, logs, replay/list API, secret rotation, SSRF defense, disable/reactivate policy.

Q9.9 senior

How would you protect a GraphQL gateway from an expensive query?

Show strong-answer signals

Authentication/tenant quotas, depth/breadth and weighted cost, persisted/allowlisted queries for high scale, resolver timeouts, batching, response byte cap, concurrency, observability.

Q9.10 senior

When should an event carry full state rather than only an ID?

Show strong-answer signals

Autonomous consumer/local view and reduced callback pressure versus payload/privacy/schema duplication. Consider snapshot/version, authority, deletion, and reconciliation.

Q9.11 staff / stretch

Define an API governance model for REST, gRPC, GraphQL, and events across 200 teams.

Show strong-answer signals

Catalog/ownership, standard identity/errors/deadlines/telemetry, schema review/compatibility CI, lifecycle/deprecation, client generation, cost quotas, exception process, production scorecards.

Q9.12 staff / stretch

Migrate a synchronous dependency graph to event-driven integration without losing correctness.

Show strong-answer signals

Identify facts/invariants, outbox, consumer idempotency, local read models, dual-run/shadow, lag/freshness SLOs, reconciliation, cutover per use case, and keep commands synchronous where immediate answer is required.

Design drills

Drill 1 API portfolio for commerce

Choose paradigms for public catalog, checkout, internal inventory, recommendation queries, order events, partner callbacks, and live shipment tracking. State why one style does not fit all.

What the interviewer is testing

Boundary-driven selection and cross-cutting consistency.

Drill 2 GraphQL gateway design

Design a GraphQL layer over ten services for web and mobile. Include batching, authorization, partial errors, caching, query cost, schema ownership/federation, and dependency failure.

What the interviewer is testing

Flexible API benefits versus centralized performance and governance risk.

Drill 3 Partner event platform

Design event subscriptions for 50,000 partners via webhook and pull API. Include schemas, replay, ordering, tenant quotas, signatures, and operations.

What the interviewer is testing

At-least-once delivery, repairability, security, and provider-scale retry control.

Common weak answers and how to improve them

“REST is JSON over HTTP.”

Show the stronger answer

Discuss resource semantics and REST constraints; JSON is only one representation.

“GraphQL prevents over-fetching, so it is faster.”

Show the stronger answer

It changes response selection but may cause expensive resolver fan-out and weak shared-cache reuse.

“gRPC is always faster.”

Show the stronger answer

Compare payload, connection reuse, CPU, proxies, browser/public clients, and measure the actual workload.

“Events decouple services.”

Show the stronger answer

They decouple timing/deployment but couple schemas, meaning, ordering, retention, and operations.

“Webhooks deliver exactly once.”

Show the stronger answer

Assume retries and duplicates; provide idempotency and reconciliation.

Primary sources and standards