GraphQL Interview Questions
Q: What is GraphQL and how does it differ from REST?
GraphQL is a query language and runtime for APIs. Key differences from REST: (1) Single endpoint vs multiple endpoints. (2) Client specifies exactly what data it needs — no over-fetching or under-fetching. (3) Strongly typed schema as the contract. (4) Multiple resources in one request (vs multiple REST calls). (5) Real-time with subscriptions. Trade-offs: more complex caching, file uploads are awkward, introspection can be a security risk.
Q: What is the N+1 problem in GraphQL and how do you solve it?
When resolving a list of N items, if each item's resolver makes a separate DB query for related data, you get N+1 queries. Solution: DataLoader — batch and cache per-request. DataLoader collects all IDs requested in a tick, makes one batched query, and distributes results back to each resolver.
import DataLoader from 'dataloader';
const userLoader = new DataLoader(async (ids: readonly string[]) => {
const users = await db.users.findMany({ where: { id: { in: ids as string[] } } });
return ids.map(id => users.find(u => u.id === id) ?? null);
});
// In resolver
posts: {
author: (post) => userLoader.load(post.authorId), // batched automatically
}Q: What is the difference between a query and a mutation?
Queries are read operations — they should have no side effects and can be executed in parallel. Mutations are write operations — they run serially (one at a time) in the order they appear. By convention, queries are idempotent (same result each call) and mutations change server state.
Q: What are fragments and why use them?
Fragments are reusable field selections defined once and spread into queries with ...FragmentName. They eliminate duplication when the same fields are needed in multiple queries, make queries more readable, and keep client-side field specifications consistent. Apollo Client co-locates fragments with the components that use them.
Q: How do you handle authentication in GraphQL?
Pass the token in the Authorization HTTP header (same as REST). In the GraphQL context function, validate the token and attach the user to context. Each resolver can then check context.user for authentication. For field-level auth, use schema directives (@auth) or check permissions inside resolvers. Never expose sensitive fields without auth checks.
Q: What is introspection and should you disable it in production?
Introspection allows clients to query the schema itself (what types/fields/queries exist). It's used by tools like GraphiQL and code generators. In production, disable introspection to avoid exposing your schema structure to attackers — this reduces the attack surface for query crafting. Allow it for authenticated internal clients if needed.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free