The Core Idea
Instead of many fixed endpoints, one endpoint accepting a query document describing exactly the data needed:
# client asks for precisely this shape:
query TripScreen($id: ID!) {
trip(id: $id) {
status
etaMinutes
driver { name rating photo }
fare { total currency }
}
}
REST problem it targets:
/trips/123 returns 40 fields; mobile needs 6 → over-fetching
screen also needs driver + fare → 3 round trips → under-aggregation
GraphQL: ONE round trip, exactly the requested fields,
shape decided by CLIENT not by server endpoint designer
Schema as Contract
type Trip {
id: ID!
status: TripStatus!
driver: Driver!
fare: Fare!
}
type Query { trip(id: ID!): Trip }
Strongly typed, introspectable — tooling generates clients, validates queries at build time. Evolution follows the same additive rules as REST (add fields freely; removals are breaking).
Resolvers: Where Cost Hides
each field maps to a RESOLVER function:
trip() → DB lookup
driver{} → another lookup per trip!
fare{} → another
naive execution = N+1 query explosion:
list 20 trips → 1 + 20(driver) + 20(fare) = 41 backend calls
The standard fix is dataloader batching:
collect all field-level lookups in a tick → batch them:
41 calls → 3 calls (trips, batched drivers, batched fares)
every serious GraphQL deployment lives or dies by dataloader
discipline; forgetting it is THE classic production incident
The Server-Side Cost Ledger
| Concern | Problem | Mitigation |
|---|---|---|
| Arbitrary query depth | One query = unbounded work | Depth/complexity limits |
| Caching | POST bodies defeat HTTP caching | APQ, edge caching, entity caches |
| Expensive ad-hoc queries | Clients can demand anything | Persisted queries (allowlist) |
| N+1 resolvers | Backend stampedes | Dataloader batching |
| Auth granularity | Field-level authz complexity | Field policies in schema |
Persisted queries deserve emphasis for public APIs: clients ship query IDs instead of arbitrary text, servers execute only allowlisted queries — flexibility for your apps without handing strangers a query language against your database.
When GraphQL Fits
✓ multiple diverse clients (mobile, web, TV) needing different shapes
✓ aggregation across many services (GraphQL as BFF layer)
✓ rapidly evolving frontend needs outpacing API releases
✗ simple CRUD backends (REST is less machinery)
✗ cache-heavy public reads (HTTP caching forfeited)
✗ internal service-to-service (gRPC contracts fit better)
Interview Framing
GraphQL questions test cost-awareness of flexibility. Scored answer: state the win (client-shaped single round-trip), then immediately price it — resolver N+1 + dataloaders, caching strategy, complexity limits. Interviewers probe “why doesn’t everyone use this?” expecting the caching and persisted-query answers; candidates who only sell benefits get exposed.
Premium Content
Unlock GraphQL and all premium lessons with a subscription.
From ₹199.99/year — See plans