█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/REST APIs/GraphQL as Alternative
50 minIntermediate

GraphQL as Alternative

After this lesson, you will be able to: Compare GraphQL and gRPC to REST: what each is, when each is better, when each is worse, and the tradeoffs.

GraphQL and gRPC are the two main REST alternatives. Knowing the tradeoffs of all three makes you sound senior in interviews and helps you pick the right tool for a given problem.

Prerequisites:Testing REST APIs

What GraphQL is

A query language for your API + a runtime. Created at Facebook (2012, open-sourced 2015). Single endpoint (`/graphql`). Clients send a query specifying EXACTLY which fields they want. Server returns just those. Strongly typed schema (SDL, Schema Definition Language). Big ecosystem: Apollo, Relay, urql on clients; Apollo Server, Hot Chocolate, graphql-yoga on servers.

Sample GraphQL query + response

Compare to REST.

json
# Query (sent by client)
query {
user(id: 42) {
name
email
posts(limit: 5) {
title
createdAt
}
}
}
# Response
{
"data": {
"user": {
"name": "Alex",
"email": "[email protected]",
"posts": [
{ "title": "Hello", "createdAt": "..." }
]
}
}
}
# REST equivalent: GET /users/42 + GET /users/42/posts?limit=5
# = 2 requests, more data than needed, client must combine.

When GraphQL is better

Mobile clients (bandwidth matters; under-fetching + over-fetching are real costs). Complex nested data with varying client needs (one screen wants a + b; another wants a + c). Backend-for-Frontend (BFF) layer that wraps many microservices. Frontend teams that move fast + don't want to coordinate every endpoint change with backend.

When REST is better

Simple CRUD APIs (REST is less ceremony). Public APIs (REST is universal; GraphQL has a learning curve). File uploads + downloads (REST handles binary well; GraphQL is awkward). When HTTP caching matters (GET requests cache; POST GraphQL queries don't). When you don't have the team capacity for GraphQL tooling.

GraphQL schema example (SDL)

Type-first design.

tsx
type User {
id: ID!
email: String!
name: String!
posts(limit: Int = 10): [Post!]!
}
type Post {
id: ID!
title: String!
body: String!
author: User!
}
type Query {
user(id: ID!): User
users(limit: Int = 20): [User!]!
}
type Mutation {
createUser(email: String!, name: String!): User!
}

💡 The hidden complexity

GraphQL solves under/over-fetching but introduces: • N+1 queries on the server (use DataLoader to batch). • Auth at the field level (every resolver needs to know who's calling). • Rate limiting harder (one query = unknown DB cost). • Caching harder (no URL = no HTTP cache). • Schema evolution different (deprecate fields, never delete). REST defaults are 'good enough' for most teams; GraphQL is a real investment.

gRPC: the third option, for service-to-service

gRPC is Google's high-performance RPC framework. Instead of resources and verbs, you define services and methods in a `.proto` file (Protocol Buffers), and gRPC generates strongly-typed client and server code in many languages. It serializes to a compact binary format over HTTP/2, which makes it much faster and smaller on the wire than JSON, and it supports streaming in both directions. Where it shines: internal microservice-to-microservice communication where speed, strict contracts, and code generation matter more than human-readability. Where it does not fit: public browser-facing APIs (browsers cannot speak raw gRPC without a proxy like gRPC-Web, and the binary payloads are not human-friendly). The rule of thumb across all three: REST for public and CRUD APIs, GraphQL for flexible client-driven product APIs, gRPC between your own backend services.

A gRPC service in a .proto file

The .proto is the contract; gRPC generates typed client + server stubs from it.

tsx
// user.proto
syntax = "proto3";
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc ListUsers (ListUsersRequest) returns (stream User); // server streaming
}
message GetUserRequest {
string id = 1;
}
message User {
string id = 1;
string email = 2;
string name = 3;
}
// `protoc` generates client + server code in Go, TypeScript, Python, Java, etc.
// Both sides share the same contract, so a breaking change is a compile error,
// not a 3am production surprise.

Common mistakes

Picking GraphQL because 'it's modern' without considering team capacity. No DataLoader leading to catastrophic N+1 queries on every nested field. Treating GraphQL mutations like REST POSTs; they're flexible and can mutate many things in one call. Forgetting query depth/complexity limits, letting malicious clients DoS your server with deeply nested queries. Reaching for gRPC on a public browser-facing API, where REST or GraphQL fit far better than binary RPC.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Testing REST APIs
Back to REST APIs
Passion Project: Production-Grade REST API→