patterntypescriptgraphqlTip
Apollo Server plugins — lifecycle hooks for logging, tracing, and custom logic
Viewed 0 times
@apollo/server 4.x
pluginslifecycle hooksrequestDidStartloggingtracingApolloServerPluginmiddleware
Problem
Cross-cutting concerns like request logging, error reporting, and performance tracing are copy-pasted into resolvers or middleware. There's no clean way to hook into GraphQL-specific lifecycle events from Express middleware.
Solution
Write Apollo Server plugins to hook into GraphQL lifecycle events.
import { ApolloServerPlugin, GraphQLRequestListener } from '@apollo/server';
const loggingPlugin: ApolloServerPlugin = {
async requestDidStart(requestContext) {
const start = Date.now();
console.log(`[GQL] ${requestContext.request.operationName ?? 'anonymous'}`);
return {
async didEncounterErrors({ errors }) {
errors.forEach(e => console.error('[GQL Error]', e.message, e.extensions));
},
async willSendResponse() {
console.log(`[GQL] completed in ${Date.now() - start}ms`);
},
};
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [loggingPlugin, ApolloServerPluginUsageReporting()],
});Why
Plugins have access to GraphQL-specific context (operation name, variables, errors) that HTTP middleware cannot see. They compose cleanly and can be extracted into packages.
Gotchas
- Plugin hooks are async — return a promise or use async/await; sync errors can crash the plugin silently
- ApolloServerPluginDrainHttpServer is required for graceful shutdown when using HTTP servers
- Schema reporting and usage reporting plugins send data to Apollo Studio — disable in development or use self-hosted analytics
- Plugins run in the order they are declared in the plugins array
Context
Adding logging, monitoring, or custom behaviour to Apollo Server request handling
Revisions (0)
No revisions yet.