Choosing Between REST, GraphQL, and tRPC for Modern Frontend Data Layers

Team 6 min read

#frontend-architecture

#data-layer

#rest-graphql-trpc

Introduction

Modern frontend apps rely on data layers that fetch, shape, and cache information from backends. REST, GraphQL, and tRPC each offer different philosophies, trade-offs, and optimizations. There’s no one-size-fits-all solution, so the right choice depends on your stack, team, and product requirements. This guide breaks down the strengths and drawbacks of each approach and provides a practical framework for decision-making.

REST in the modern frontend

REST remains a reliable baseline for many projects. Its strengths include ubiquity, clear HTTP semantics, and strong native caching via HTTP headers and CDNs.

  • Pros

    • Simple, stable contracts with well-understood tooling.
    • Excellent HTTP caching possibilities (ETags, Cache-Control, CDN caching).
    • Broad client support and straightforward versioning strategies.
    • Loose coupling between client and server surface.
  • Cons

    • Over-fetching and under-fetching are common without multiple round-trips.
    • Composing data across resources can lead to multiple requests and more boilerplate.
    • Evolving APIs can require versioning or complex feature flags.
  • Best-fit scenarios

    • Public APIs and microservices with stable, well-defined resources.
    • Apps where caching and CDN distribution are priorities.
    • Teams that favor conventional REST endpoints and existing tooling.

GraphQL: powerful but not universal

GraphQL offers a flexible query model and a single endpoint with a strongly typed schema, which can dramatically reduce over-fetching for complex UIs.

  • Pros

    • Clients request exactly what they need, reducing over-fetching.
    • Strongly typed schema with introspection improves DX and tooling.
    • Single endpoint can aggregate data from multiple services.
    • Excellent for complex UIs and dashboard-style apps with varied data shapes.
  • Cons

    • Steeper learning curve and more complex server setup.
    • Caching is more nuanced; require persisted queries or client-side normalization.
    • Overuse can lead to complex queries and performance pitfalls if not managed (e.g., deep query depth).
    • Less suitable for simple CRUD APIs or strict external public APIs without a gateway.
  • Best-fit scenarios

    • Data-heavy frontends with highly variable data shapes across views.
    • Teams that want centralized data composition and strong type safety across the stack.
    • Projects where a single graph can expose multiple underlying services.

tRPC: end-to-end typesafe RPC for TS stacks

tRPC provides end-to-end typesafe RPC calls over HTTP, primarily designed for TypeScript-first stacks (like Next.js/React + Node).

  • Pros

    • End-to-end type safety; clients automatically infer types from server procedures.
    • Minimal boilerplate: no separate schema language or code generation required in many setups.
    • Simple developer experience for TS-heavy teams and monorepos.
    • Clear separation of concerns when your API surface is tightly aligned with your backend logic.
  • Cons

    • Not ideal for public third-party clients; best for internal apps or partner integrations with TS-first access.
    • Caching is more challenging to share across caches and CDNs; requires custom strategies.
    • Tight coupling between frontend and backend implementations can reduce platform-agnosticism.
  • Best-fit scenarios

    • Internal applications and admin UIs built on a TS-first stack.
    • Teams prioritizing DX and rapid iteration with end-to-end type safety.
    • Monorepos or architecture where a single data layer serves multiple frontend apps.

Criteria to weigh

When evaluating REST, GraphQL, and tRPC, consider:

  • Typing and developer DX
    • GraphQL and tRPC offer strong typing; REST can be typed via OpenAPI but is less integrated by default.
  • Data shape and query flexibility
    • GraphQL shines with flexible data shapes; REST excels with stable resources; tRPC focuses on procedure calls.
  • Caching and performance
    • REST leverages HTTP caching well; GraphQL requires more sophisticated caching; tRPC needs custom caching approaches.
  • Tooling and ecosystem
    • REST has broad tooling; GraphQL has mature tooling for schema stitching, clients, and server runtimes; tRPC relies on TS tooling and modern frameworks.
  • Security and access control
    • REST and GraphQL have well-understood security patterns; tRPC requires careful consideration of exposure and auth boundaries in internal apps.
  • Evolution and versioning
    • REST supports versioned endpoints; GraphQL evolves via schema changes with deprecation strategies; tRPC benefits from type-safe refactors but can require coordinated changes across the stack.
  • Adoption and team readiness
    • Choose based on team strengths: REST for broad teams, GraphQL for data-oriented frontends, tRPC for TS-centric teams.

When to choose REST

  • You need broad external consumption with stable contracts.
  • HTTP caching and CDN efficiency are critical.
  • Your API surface maps cleanly to resources and standard CRUD operations.
  • You want simple, incremental onboarding for new developers and services.

When to choose GraphQL

  • Your UI has complex data requirements that pull from multiple sources.
  • You want to minimize over-fetching and tailor responses per view.
  • You benefit from a strongly typed schema and a cohesive developer DX across frontend and backend.
  • You’re building dashboards, admin panels, or mobile apps where data shaping is frequent and diverse.

When to choose tRPC

  • Your stack is TypeScript-heavy and you want end-to-end type safety with minimal boilerplate.
  • You control both frontend and backend and want fast iteration in a monorepo.
  • You don’t need to expose a public API to external clients beyond TS-first consumers.
  • You’re aiming for a single, cohesive data layer without much cross-service orchestration.

A practical decision guide

  • Step 1: Do you need external public clients or partners consuming the API? If yes, consider REST or GraphQL. If internal only, tRPC is a strong option in TS-heavy stacks.
  • Step 2: Is your data surface highly dynamic and shape-heavy across views? Consider GraphQL.
  • Step 3: Do you prioritize end-to-end typesafe development across frontend and backend? Consider tRPC.
  • Step 4: How important is caching at the HTTP/CDN level? REST offers the most straightforward benefits here.
  • Step 5: Do you require multiple services to be composed into a single API? GraphQL can simplify data orchestration, while REST can do this via gateways; tRPC is best when a single, coherent backend surface exists.

Real-world scenarios

  • Admin dashboard in a Next.js app with a TS-heavy backend: tRPC can deliver a fast, cohesive experience with strong type guarantees, while keeping internal boundaries clean.
  • Public storefront API used by mobile apps and partners: REST may be the simplest, most interoperable choice with robust caching and clear versioning. GraphQL is an option if data needs are highly variable across clients.
  • Data-intensive analytics UI with varied data shapes: GraphQL helps by letting each view request precisely what it needs, reducing network payloads and enabling flexible composition.

Pitfalls and best practices

  • REST: avoid endpoint sprawl with clear resource modeling and consider versioning strategies that minimize breaking changes.
  • GraphQL: implement query depth limits and persisted queries to manage complexity; plan caching strategies early.
  • tRPC: document boundaries clearly to prevent backend/frontend coupling from growing too tight; consider hybrid approaches for external clients if needed.
  • Across all approaches: monitor performance, define clear pagination and rate-limiting policies, and align with your security model (auth, authorization, and data masking).

Conclusion

REST, GraphQL, and tRPC each offer compelling paths for modern frontend data layers. REST remains ideal for public APIs and straightforward caching; GraphQL excels where data shapes are dynamic and client flexibility matters; tRPC shines in TS-centric environments where end-to-end type safety and fast iteration are paramount. The best choice often isn’t a single winner but a pragmatic mix: core internal apps might leverage tRPC for speed and safety, public-facing surfaces might rely on REST for compatibility, and select features or dashboards could benefit from GraphQL’s flexible data fetching.