GraphQL
Real Incident: Facebook iOS App, 2012
Facebook's iOS app needed 7 REST calls to render one News Feed screen. Each returned 80% unused data. Backend was drowning in custom endpoints: /mobile/feed, /mobile/feed-v2, /mobile/feed-slim. They built GraphQL. One query, exactly the data you need, zero waste.
The 30-Second Explanation
GraphQL = a query language for APIs where the client specifies exactly what data it wants. One endpoint, flexible queries, no over/under-fetching.
REST Pain Points
Over-fetching, under-fetching, N+1 endpoints, versioning hell
GraphQL Solution
Ask for exactly what you need. One request. Type-safe. Self-documenting.
REST vs GraphQL — The Core Difference
| Aspect | REST | GraphQL |
|---|---|---|
| Endpoints | Many (/users, /posts, /comments) | One (/graphql) |
| Data shape | Server decides what to return | Client decides what to fetch |
| Over-fetching | Common (get 20 fields, need 3) | Impossible (ask for only what you need) |
| Under-fetching | Common (need 3 calls for one view) | Impossible (get everything in 1 query) |
| Versioning | URL-based (/v1/, /v2/) | No versions needed (add fields, deprecate old ones) |
| Caching | Easy (HTTP caching by URL) | Harder (all requests go to same URL) |
| Learning curve | Low | Medium |
When to Use GraphQL vs REST
| Choose GraphQL When | Choose REST When |
|---|---|
| Mobile apps (bandwidth-sensitive) | Simple CRUD APIs |
| Multiple client types (web, iOS, Android, watch) | Heavy caching needed |
| Deeply nested/related data | File upload/download |
| Rapid frontend iteration | Simple microservice-to-microservice |
| Need to avoid endpoint explosion | Team unfamiliar with GraphQL |
Key Concepts
| Concept | What | Analogy |
|---|---|---|
| Query | Read data (like GET) | "Show me this data" |
| Mutation | Write/update data (like POST/PUT/DELETE) | "Change this data" |
| Subscription | Real-time updates (WebSocket) | "Notify me when this changes" |
| Schema | Contract defining all types and operations | The menu |
| Resolver | Function that fetches data for a field | The kitchen |
| Type | Shape of data (User, Post, Comment) | The recipe |
The N+1 Problem — GraphQL's Biggest Trap
The problem: Query all users + their posts. Naive implementation: 1 query for users + N queries for each user's posts.
| Approach | Queries | Used By |
|---|---|---|
| Naive resolvers | 1 + N (one per user) | Nobody (in production) |
| DataLoader (batching) | 2 (users + all posts in one batch) | Facebook, GitHub, Shopify |
| Join optimization | 1 (database join) | Hasura, PostGraphile |
DataLoader pattern: Collect all IDs requested in a single tick, batch into one DB query. This is how every production GraphQL server solves N+1.
Security Concerns (What Interviewers Ask)
| Threat | What | Mitigation |
|---|---|---|
| Deep queries | Nested query 20 levels deep → kills server | Query depth limiting (max 10) |
| Expensive queries | Request every field on every type | Query complexity scoring + cost limit |
| DDoS via query | Malicious query that takes 30s to resolve | Timeout + persisted queries (whitelist) |
| Introspection | Attacker discovers your entire schema | Disable introspection in production |
Real Systems
| Company | Why GraphQL | Notable |
|---|---|---|
| GitHub | REST API had 300+ endpoints, too many for clients | v4 API is GraphQL-only |
| Shopify | 1M+ merchants with different data needs | Storefront API = GraphQL |
| Netflix | Different UIs (TV, phone, browser) need different data | Studio search API |
| Timeline composition from many sources | Internal federation | |
| Airbnb | Complex nested data (listing → host → reviews → photos) | Frontend-driven queries |
GraphQL Federation (Microservices)
Problem: You have 20 microservices. Each owns part of the data. Client needs data from 5 of them in one request.
Solution: GraphQL Federation — each service defines its part of the schema. A gateway merges them into one unified graph.
| Concept | What |
|---|---|
| Subgraph | One microservice's GraphQL schema |
| Gateway | Composes subgraphs into unified schema |
| @key | Defines entity identity across services |
| Query plan | Gateway figures out which services to call |
Used by: Netflix, Expedia, Walmart (Apollo Federation).
REST + GraphQL (The Pragmatic Approach)
Most teams don't go all-in on either. Common pattern:
| Layer | Protocol | Why |
|---|---|---|
| External API (clients) | GraphQL | Flexible, client-driven |
| Service-to-service | REST or gRPC | Simple, cacheable, typed (gRPC) |
| Internal batch ops | REST | File upload, webhooks, simple CRUD |
The 3 Mistakes That Get You Rejected
Don't Say These
- "GraphQL replaces REST" — No. They coexist. REST is better for simple APIs, caching, and service-to-service. GraphQL shines for complex client needs.
- "GraphQL is faster" — Not inherently. A naive GraphQL server can be SLOWER (N+1 problem). Speed depends on resolver implementation and DataLoader usage.
- "No versioning needed means no breaking changes" — You still need discipline. Deprecate fields gracefully. Removing a field without warning breaks clients.
Interview Answer Template
"For [system] with [multiple clients / complex data], I'd use GraphQL because [reason: flexible queries, avoid endpoint explosion, reduce mobile bandwidth]. I'd address N+1 with DataLoader batching, security with query depth/complexity limits, and caching with [persisted queries / CDN-level caching]. For service-to-service, I'd keep REST/gRPC."
Quick Recall Card
| Question | Answer |
|---|---|
| Core advantage over REST? | Client gets exactly what it asks for (no over/under-fetch) |
| N+1 solution? | DataLoader (batch + cache within single request) |
| Biggest security risk? | Deep/expensive queries → timeout + complexity limiting |
| When NOT to use? | Simple CRUD, heavy caching needs, file operations |
| Federation? | Gateway composes multiple subgraph schemas into one |
| Caching challenge? | All queries go to same URL → can't use HTTP cache naively |