SE

GraphQL and gRPC

Must-know concept1.5 hIntermediate

Beyond REST — when to use alternatives.

REST is not the only option. GraphQL lets clients ask for exactly the fields they want; gRPC gives schema-first, binary RPC ideal between services. Both shine in specific situations — and both have costs REST doesn't.

The big idea

Three different bets about who pays the complexity cost:

AttributeRESTGraphQL / gRPC
ContractResource + URL conventionsSchema-first (`.graphql` / `.proto`)
EncodingJSONJSON (GQL) / binary (gRPC)
Multiple fetchesMultiple round tripsGQL: one query, many fields. gRPC: streams.
Best forPublic APIs, browser, simple casesVaried clients (GQL), internal services (gRPC)
Complexity taxOn the clientOn the server

GraphQL: clients ask for what they need

The pitch: one endpoint, one query language, the client chooses fields. No more "5 endpoints for 5 screens."

query HomeScreen($userId: ID!) {
  user(id: $userId) {
    name
    avatar
    orders(last: 5) {
      id
      total_cents
      status
      items { product { name } quantity }
    }
    recommendations(limit: 8) {
      id
      name
      price_cents
    }
  }
}

One round trip, the exact shape the screen needs, no over- or under-fetching.

Where GraphQL shines

Many client types
Mobile, web, partners all want different fields from the same data.
Aggregating multiple backends
A GraphQL gateway fans out to REST/gRPC services and stitches results.
Evolving APIs
Adding fields is non-breaking; deprecating fields is built-in.

Where it hurts

gRPC: schema-first RPC over HTTP/2

Define services and messages in a .proto file; generate strongly-typed client and server stubs in any language.

syntax = "proto3";
 
service Orders {
  rpc Get(GetOrderRequest) returns (Order);
  rpc Stream(StreamRequest) returns (stream Order);
  rpc Create(CreateOrderRequest) returns (Order);
}
 
message GetOrderRequest { uint64 id = 1; }
 
message Order {
  uint64 id = 1;
  uint64 user_id = 2;
  uint32 total_cents = 3;
  Status status = 4;
 
  enum Status { NEW = 0; PAID = 1; SHIPPED = 2; CANCELLED = 3; }
}

Where gRPC shines

Service-to-service
Lower latency than JSON-over-HTTP, contract-checked by the compiler.
Streaming
Server-side, client-side, and bi-directional streams are first-class.
Polyglot internal stacks
One .proto, ten language clients generated.

Where it hurts

Picking between them

  1. External / browser-facing API?

    Default to REST. Reach for GraphQL when client diversity makes REST endpoint sprawl.

  2. Service-to-service, internal?

    Default to gRPC. Schema-first contracts and binary perf are the win.

  3. Many client teams, varied screens?

    GraphQL gateway in front of gRPC services is a very common modern shape.

  4. High-throughput streaming?

    gRPC streams or a dedicated streaming protocol (WebSockets, SSE).

In practice

The wrong question is "should I use GraphQL/gRPC?" The right question is "what problem am I solving that REST doesn't?" If you can't name one, REST is still the cheapest correct answer.

Key takeaways

  • GraphQL lets clients ask for exactly the fields they need — great for varied client types.
  • GraphQL costs you HTTP caching and forces you to solve N+1 with batching/DataLoader.
  • gRPC is schema-first, binary, and shines between services.
  • gRPC streaming is first-class, but browsers need gRPC-Web.
  • A common shape: REST or GraphQL at the edge, gRPC between internal services.

Checkpoint questions

Use these to test whether the lesson is clear enough to explain without rereading.

  1. 1What complexity does GraphQL move from server teams to client teams or schema owners?
  2. 2Why can GraphQL make caching and N+1 query prevention harder?
  3. 3What makes gRPC a strong fit for internal service-to-service calls?
  4. 4Which API style would you choose for browser clients, mobile clients, and internal streaming calls?

References

External resources for going deeper after the lesson above.