REST vs GraphQL vs gRPC

Updated:

Three API styles dominate modern backend design: REST (the universal default), GraphQL (the query-driven challenger), and gRPC (the high-performance contender). They are not directly interchangeable — each makes different trade-offs around coupling, performance, tooling, and how clients evolve. This guide compares them on the dimensions that determine real-world fit, so you can pick deliberately instead of by default.

REST — the default that won the web

REST relies on HTTP verbs (GET, POST, PUT, DELETE) and resource-shaped URLs ('/users/123/posts'). It is supported by every HTTP client, cacheable by every CDN, debuggable with curl, and indexable by browsers. The cost: each new requirement often means a new endpoint or query parameter, and over-fetching / under-fetching is common when clients have diverse needs.

GraphQL — clients ask exactly what they need

GraphQL exposes a single endpoint that accepts queries describing the exact data shape the client wants. This eliminates over-fetching and gives front-end teams strong independence. The trade-offs: caching is harder (no per-URL cacheability), query depth limits and persisted queries are needed to prevent abuse, and the server is now responsible for arbitrary join planning.

gRPC — schemas, codegen, and binary speed

gRPC uses Protocol Buffers for schema definition and HTTP/2 for transport, giving you small binary payloads, streaming, and language-agnostic code generation. It is the fastest and most type-safe option for service-to-service traffic. The trade-offs: not directly callable from browsers (you need gRPC-Web), harder to debug by hand, and tooling is more specialized than REST.

Schema evolution

REST evolves by adding new endpoints or versioned URLs. GraphQL evolves by adding fields (deprecate, don't remove) and is generally backwards-compatible by design. gRPC uses Protocol Buffers' explicit field numbers — adding fields is safe, but never reuse a number. Each model works; the difference is how disciplined your team needs to be.

Browser support

  • REST: works everywhere, including HTML forms.
  • GraphQL: works in any browser that can POST JSON.
  • gRPC: not directly — requires a gRPC-Web proxy that translates from browser-friendly HTTP/1.1 to native gRPC.

Caching and CDN

REST is the clear winner for browser and CDN caching: GET requests have stable URLs and standard HTTP cache headers. GraphQL POST requests defeat HTTP caching by default (workarounds: persisted queries, GET with hash, or response-level caching like Apollo). gRPC traffic typically does not go through public CDNs at all.

Observability and debugging

REST is the easiest to debug: tail an access log and you see meaningful URLs. GraphQL hides operation intent inside the query body, so observability requires query naming conventions and APM tools that understand GraphQL. gRPC traffic is binary and needs specialized tracing (OpenTelemetry, grpcurl).

When to pick which

  • Public API consumed by third parties: REST (universal client support).
  • Frontend with many entity-shape variants (mobile, desktop, embedded): GraphQL.
  • Internal microservice traffic at scale: gRPC.
  • Real-time bidirectional streams: gRPC (streaming) or GraphQL subscriptions.
  • Quick prototype, single client: REST.

Preguntas frecuentes

Can I use multiple styles in the same backend?
Yes, and many companies do. Common pattern: gRPC for service-to-service, GraphQL for the API gateway your front-end calls, and REST for public partner integrations.
Does GraphQL make my backend slower?
Not inherently, but it makes performance issues less predictable. You must add query complexity analysis, depth limits, and N+1 query batching (DataLoader) to keep latency stable.
What about tRPC?
tRPC is a TypeScript-specific RPC framework that gives you end-to-end typing without code generation. It's excellent for TypeScript monorepos but does not help with cross-language teams.

In summary

There is no universally best API style — only the right fit for your clients, scale, and team. Pick REST when you want to be easy to consume, GraphQL when your clients diverge in shape, and gRPC when performance dominates. Many production systems use all three at different layers of the stack.