Working with Resolver Context
1. Creating Context Object
| Property | Use |
| user | Authenticated principal |
| db | ORM/client instance |
| loaders | DataLoader instances |
| req / headers | Raw HTTP request |
| logger | Per-request scoped logger |
| requestId | Trace correlation |
2. Adding User Authentication
Example: Verify JWT in context
context: async ({ req }) => {
const token = req.headers.authorization?.replace(/^Bearer /, "");
const user = token ? await verifyJWT(token) : null;
return { user };
}
3. Adding Database Connections
| Strategy | Detail |
| Singleton client | Prisma/Knex shared across requests |
| Per-request transaction | Begin/commit around operation |
| Read replica | Route Query → replica, Mutation → primary |
4. Adding Data Loaders
Example: Per-request loaders
function createLoaders(db) {
return {
userById: new DataLoader(ids => batchUsers(db, ids)),
postsByUser: new DataLoader(ids => batchPostsByUser(db, ids))
};
}
context: ({ req }) => ({ db, loaders: createLoaders(db) })
Warning: Always create loaders per-request — never share across requests (cache pollution).
| Field | Use |
| ip | Rate limiting |
| userAgent | Analytics |
| locale / Accept-Language | i18n |
| headers | Custom integration headers |
6. Sharing Context Across Resolvers
| Pattern | Detail |
| Shape stable | Use TypeScript type for context |
| Avoid mutation | Treat context as readonly during execution |
| Lazy init | Getters for expensive resources |
7. Implementing Context Functions
Example: Apollo Server context fn
const server = new ApolloServer({ schema });
await startStandaloneServer(server, {
context: async ({ req }) => ({ user: await auth(req), db, loaders: createLoaders() })
});
8. Using Context for Authorization
Example: Role check
Query: {
adminStats: (_, __, { user }) => {
if (user?.role !== "ADMIN") throw new GraphQLError("Forbidden", { extensions: { code: "FORBIDDEN" } });
return computeStats();
}
}
9. Adding Logger to Context
| Pattern | Benefit |
| Child logger per request | Inherits requestId, userId |
| Pino / Winston | Structured JSON logs |
| OpenTelemetry | Auto-correlates logs ↔ spans |
10. Managing Context Lifecycle
| Phase | Action |
| Create | Build per request |
| Use | Available in every resolver |
| Cleanup | Plugin willSendResponse closes resources |
| Subscriptions | Build per WebSocket connection AND per operation |