FSD Frontend System Design

Part I β€” The Pipes Β· Lesson 1.8

Choosing: REST vs GraphQL vs gRPC

In one linePick by who the clients are and how nested the data is β€” not by what's newest.

Where you've seen itShopify ships all three β€” REST for public third-party apps, GraphQL for its own admin UI, gRPC between internal services.

  • Time12 min
  • DiagramDecision tree + comparison matrix
  • Chapter1 Β· Networking

Diagram

diagram
DECISION TREE

                    Who calls this API?
                            β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό                   β–Ό                   β–Ό
  Unknown 3rd          Your own            Another service
  parties              frontend            (server-to-server)
        β”‚                   β”‚                   β”‚
        β–Ό                   β–Ό                   β–Ό
     REST            Is the data          High volume or
   (browsable,        deeply nested        streaming?
    cacheable,        / per-screen?             β”‚
    versioned)             β”‚              β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”
                     β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”        β–Ό           β–Ό
                     β–Ό           β–Ό      gRPC        REST
                  GraphQL      REST   (binary,    (simple,
                                       typed)     debuggable)
diagram
COMPARISON MATRIX

                    REST        GraphQL       gRPC
  ────────────────────────────────────────────────────
  Payload           JSON        JSON          Protobuf
  Transport         HTTP/1-3    HTTP POST     HTTP/2
  HTTP caching      free        manual        none
  Over-fetching     yes         no            no
  Round trips       many        one           one
  Browser support   native      native        proxy needed
  Schema/types      OpenAPI     built-in      built-in
  Streaming         SSE/WS      subscriptions native
  Debug with curl   easy        awkward       no

How it works

  1. Start from the client. Unknown third parties β†’ REST. Your own app β†’ REST or GraphQL. Another service β†’ gRPC.
  2. Then check data shape. Nested, screen-specific trees favour GraphQL; flat entities favour REST.
  3. Then check caching needs. If CDN caching is the main lever, REST wins outright.
  4. Then check volume. Internal, high-throughput, latency-sensitive β†’ gRPC.
  5. Combine freely β€” a BFF that speaks GraphQL outward and gRPC inward is a normal, defensible answer.
diagram
THE COMMON REAL-WORLD SHAPE

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  GraphQL   β”Œβ”€β”€β”€β”€β”€β”€β”   gRPC   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Browser β”‚ ─────────► β”‚ BFF  β”‚ ───────► β”‚ Services   β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β””β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
   one query per screen   aggregates        typed, binary,
                          + caches          fast internally

Trade-offs

Don't choose GraphQL ifDon't choose REST ifDon't choose gRPC if
CDN caching is your main winScreens need 5+ nested resourcesThe browser must call it directly
Team can't own query governancePayloads are 10Γ— what the UI usesYou need curl-level debuggability

Interview angle

"Design the API layer for a mobile-heavy social app."

  • Mobile bandwidth + per-screen nesting β†’ GraphQL at the edge, one query per screen.
  • Keep images and static content on plain REST/CDN URLs so they stay cacheable.
  • Internal fan-out (feed, ranking, notifications) over gRPC behind a BFF.

Recap

  • Client type first, data shape second, caching third, volume fourth.
  • These are layers, not rivals β€” most real systems run all three.
  • Naming the trade-off you accepted matters more than the choice itself.