This Theme 9 chapter focuses on API style fit for latency, schema evolution, and DX.
In real-world design, this material helps drive decisions using measurable constraints: latency budget, blast radius, contract stability, and integration operating cost.
For system design interviews, it provides a clear narrative: why this approach was chosen, which alternatives were considered, and which operational risks must be made explicit.
Practical value of this chapter
Design in practice
Choose API style by client profile: mobile, backend-to-backend, or federated UI.
Decision quality
Score contract options by latency, payload efficiency, schema evolution, and governance effort.
Interview articulation
Present a decision matrix instead of a one-style-fits-all position.
Failure framing
Account for over/under-fetch risk, observability complexity, and tooling lock-in.
Source
gRPC Introduction
Official guide to gRPC service model and contracts.
In real systems, teams rarely pick one universal API style. The practical question is different: where you need stable external contracts, where low-latency internal RPC is critical, and where client-driven data selection matters most. This chapter compares REST, gRPC, and GraphQL through architectural trade-offs instead of technology hype.
Comparison by key criteria
| Criterion | REST | gRPC | GraphQL |
|---|---|---|---|
| Contract model | HTTP resources with OpenAPI as the external contract. | IDL contract (`.proto`) with server/client code generation. | Single graph schema with client-selected data shape. |
| Payload and serialization | Usually JSON: readable, but typically heavier on the wire. | Protobuf: more compact and often cheaper for CPU/network. | Usually JSON; payload size depends on query shape and caching policy. |
| Latency/throughput profile | Solid baseline for public APIs and partner integrations. | Often better p95 latency for internal RPC paths. | Strong client flexibility, but can lose on resolver fan-out overhead. |
| API evolution | Versioning via URI/header plus backward-compatibility policy. | Field evolution via protobuf rules (`reserved`, field numbers). | Schema evolution through deprecation and typed contracts. |
| Caching | Strong built-in HTTP cache/control mechanisms. | Caching is usually implemented at client/gateway/application layers. | Needs explicit strategy: persisted queries, normalized cache, DataLoader. |
| Best-fit context | Public APIs, partner integrations, broad tooling ecosystem. | Internal service-to-service calls, streaming, low-latency paths. | BFF/gateway for complex UI and multiple client platforms. |
How to choose in real scenarios
Scenario
Public API for external partners
Typical pick
REST
Easier onboarding, predictable HTTP contract, and strong interoperability.
Scenario
Internal service mesh with strict latency budget
Typical pick
gRPC
Binary serialization and strict IDL usually provide stable performance and contract discipline.
Scenario
Mobile and web clients with different data needs
Typical pick
GraphQL
Clients can shape data requests and reduce over-fetching/under-fetching in UI workflows.
Scenario
Mixed enterprise platform
Typical pick
Combination
Typical pattern: REST outside, gRPC inside, GraphQL as a client-facing facade/BFF.
Common anti-patterns
Recommendations
References
- Roy Fielding: REST dissertation - primary source for REST constraints and architectural style.
- gRPC Documentation - official introduction to service contracts and RPC call types.
- GraphQL Learn - official guide to schema, query/mutation, and performance practices.
- OpenAPI Specification - canonical specification for REST API contracts and data schemas.
Related chapters
- API: RPC and REST - baseline context for remote call models and network-level trade-offs.
- Inter-service communication patterns - extends protocol choice into sync/async design, retries, and backpressure.
- Customer-friendly API: convenient API for clients - practical BFF vs GraphQL framing for client-facing API design.
- API Design Patterns (short summary) - systematic contract evolution and breaking-change management.
- Learning GraphQL (short summary) - deeper coverage of schema design, resolvers, and GraphQL workflows.
- Service Discovery - runtime foundation for resilient service-to-service calls.
