Context setup in GraphQL - Time & Space Complexity
When using context setup in GraphQL, we want to know how the time to prepare data changes as the amount of input grows.
We ask: How does the work to set up context scale when many requests or data items are involved?
Analyze the time complexity of the following code snippet.
const server = new ApolloServer({
typeDefs,
resolvers,
context: async ({ req }) => {
const user = await getUserFromToken(req.headers.authorization);
const permissions = await getPermissions(user.id);
return { user, permissions };
}
});
This code sets up context for each request by fetching user info and permissions before running resolvers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Fetching user and permissions data for each request.
- How many times: Once per incoming request, sequentially.
Each request triggers two data fetches: user info and permissions.
| Input Size (requests) | Approx. Operations |
|---|---|
| 10 | 20 fetches (10 users + 10 permissions) |
| 100 | 200 fetches (100 users + 100 permissions) |
| 1000 | 2000 fetches (1000 users + 1000 permissions) |
Pattern observation: Operations grow directly with the number of requests, doubling the fetches per request.
Time Complexity: O(n)
This means the time to set up context grows linearly with the number of requests.
[X] Wrong: "Context setup happens once and is reused for all requests."
[OK] Correct: Each request needs fresh context data, so setup runs every time, making the cost grow with requests.
Understanding how context setup scales helps you explain backend performance and design efficient APIs.
"What if we cached user permissions in context? How would the time complexity change?"
Practice
context in a GraphQL server?Solution
Step 1: Understand what context provides
Context is an object that runs once per request and is accessible in every resolver, allowing shared data like user info or database clients.Step 2: Compare with other options
Defining schema types, writing resolvers, and formatting responses are separate tasks not handled by context.Final Answer:
To share data like user info or database clients across all resolvers -> Option AQuick Check:
Context shares data across resolvers [OK]
- Confusing context with schema definition
- Thinking context formats responses
- Assuming context writes resolver logic
Solution
Step 1: Recall Apollo Server context syntax
Context is defined as a function returning an object, e.g.,context: () => ({ user: getUser() }).Step 2: Identify syntax errors in other options
context = { user: getUser() } uses assignment instead of a function, C uses an object directly without a function, and D has invalid syntax missing parentheses and braces.Final Answer:
context: () => ({ user: getUser() }) -> Option BQuick Check:
Context is a function returning an object [OK]
- Defining context as a plain object
- Missing parentheses in function syntax
- Using assignment instead of property
context: () => ({ user: { id: 5, name: 'Alice' } })What will be the value of
context.user.name inside a resolver?Solution
Step 1: Analyze the context object
The context function returns an object with auserproperty containing{ id: 5, name: 'Alice' }.Step 2: Access
Accessinguser.namein resolvercontext.user.namewill give the string 'Alice' as defined.Final Answer:
'Alice' -> Option DQuick Check:
context.user.name = 'Alice' [OK]
- Confusing user id with name
- Assuming context is undefined
- Expecting null instead of string
context: () => { user: getUser() }Why does
context.user return undefined in resolvers?Solution
Step 1: Check function return behavior
The function uses curly braces but lacks a return statement, so it returns undefined by default.Step 2: Understand impact on context
Since nothing is returned,context.useris undefined in resolvers.Final Answer:
Because the function does not return the object explicitly -> Option CQuick Check:
Missing return in function = undefined context [OK]
- Omitting return in arrow function with braces
- Assuming getUser() is undefined without checking
- Thinking context must be an object, not function
Solution
Step 1: Understand async context needs
Connecting to a database and fetching user info are asynchronous operations, so context must be async and await these calls.Step 2: Evaluate options for async correctness
context: async () => { const db = await connectDB(); const user = await getUser(); return { db, user }; } correctly uses async function and awaits results before returning an object. context: { db: connectDB(), user: getUser() } is a plain object, not a function. context: () => { db: connectDB(); user: getUser(); } lacks return and awaits. context: () => ({ db: connectDB(), user: getUser() }) returns an object but does not await async calls.Final Answer:
context: async () => { const db = await connectDB(); const user = await getUser(); return { db, user }; } -> Option AQuick Check:
Async context with awaited data [OK]
- Not awaiting async calls in context
- Using plain object instead of function
- Missing return statement in function
Ready to prove it?
Pass the test and this pattern moves unknown
