Request Context in Node.js
GraphQL context is commonly used to expose request-scoped dependencies to resolvers.
For example, a request context might contain:
{
user: authenticatedUser,
requestId: "req-123",
userService,
postService,
loaders
}
A resolver can then access those values:
const resolvers = {
Query: {
me: (_, __, context) => {
return context.user;
}
}
};
Context is especially useful for authentication because authentication middleware can establish the current user before GraphQL execution begins.
It can also hold request-specific DataLoader instances. This is important because DataLoader caches should normally be scoped appropriately to a request rather than accidentally shared across unrelated users.
Avoid putting global mutable state into context simply because context is convenient. Application-wide configuration, immutable service instances, and request-specific information have different lifecycles and should be modeled accordingly.
A clean context design makes dependencies explicit and reduces the temptation to import global mutable variables from everywhere in the resolver layer.
const server = new ApolloServer({
typeDefs,
resolvers
});
const context = async ({ req }) => {
const user = await authenticateRequest(req);
return {
user,
requestId: req.headers["x-request-id"],
userService,
postService
};
};- GraphQL context is useful for request-scoped dependencies.
- Authentication information is commonly exposed through context.
- Request-specific loaders should have appropriate request lifecycles.
- Avoid using context as an uncontrolled global-state container.
Why is request-scoped context useful for GraphQL authentication?