Apollo Server Core includes a comprehensive collection of built-in plugins for usage reporting, caching, landing pages, and server management. These plugins extend server functionality through the plugin system hooks.
Plugin for reporting GraphQL usage metrics to Apollo Studio.
/**
* Enable usage reporting to Apollo Studio
* @param options - Configuration options for usage reporting
* @returns Plugin instance for usage reporting
*/
function ApolloServerPluginUsageReporting<TContext>(
options?: ApolloServerPluginUsageReportingOptions<TContext>
): ApolloServerPlugin;
/**
* Disable usage reporting (explicit opt-out)
* @returns Plugin instance that disables usage reporting
*/
function ApolloServerPluginUsageReportingDisabled(): ApolloServerPlugin;
interface ApolloServerPluginUsageReportingOptions<TContext> {
/** API key for Apollo Studio */
apiKey?: string;
/** Apollo Studio graph reference */
graphRef?: string;
/** How to handle variable values in reports */
sendVariableValues?: SendValuesBaseOptions;
/** How to handle HTTP headers in reports */
sendHeaders?: SendValuesBaseOptions;
/** Generate client info for requests */
generateClientInfo?: GenerateClientInfo<TContext>;
/** Send reports immediately (disable batching) */
sendReportsImmediately?: boolean;
/** Include request in usage reporting */
includeRequest?: (
requestContext: GraphQLRequestContext<TContext>
) => ValueOrPromise<boolean>;
}
interface SendValuesBaseOptions {
all?: boolean;
none?: boolean;
onlyNames?: string[];
exceptNames?: string[];
transform?: (options: { variables: Record<string, any> }) => Record<string, any>;
}
interface ClientInfo {
clientName?: string;
clientVersion?: string;
clientReferenceId?: string;
}
type GenerateClientInfo<TContext> = (
requestContext: GraphQLRequestContext<TContext>
) => ValueOrPromise<ClientInfo>;Usage Examples:
import {
ApolloServerBase,
ApolloServerPluginUsageReporting,
ApolloServerPluginUsageReportingDisabled
} from "apollo-server-core";
// Enable usage reporting with API key
const server = new ApolloServerBase({
typeDefs,
resolvers,
plugins: [
ApolloServerPluginUsageReporting({
apiKey: process.env.APOLLO_KEY,
sendVariableValues: { none: true }, // Don't send variable values
sendHeaders: { exceptNames: ['authorization'] }, // Don't send auth headers
}),
],
});
// Disable usage reporting explicitly
const server = new ApolloServerBase({
typeDefs,
resolvers,
plugins: [ApolloServerPluginUsageReportingDisabled()],
});
// Custom client info generation
const server = new ApolloServerBase({
typeDefs,
resolvers,
plugins: [
ApolloServerPluginUsageReporting({
generateClientInfo: ({ request }) => ({
clientName: request.http?.headers.get('x-client-name') || 'unknown',
clientVersion: request.http?.headers.get('x-client-version') || '1.0.0',
}),
}),
],
});Plugin for reporting GraphQL schema changes to Apollo Studio.
/**
* Enable schema reporting to Apollo Studio
* @param options - Configuration options for schema reporting
* @returns Plugin instance for schema reporting
*/
function ApolloServerPluginSchemaReporting(
options?: ApolloServerPluginSchemaReportingOptions
): ApolloServerPlugin;
interface ApolloServerPluginSchemaReportingOptions {
/** Override the schema to report */
overrideReportedSchema?: GraphQLSchema;
/** Endpoint URL for schema reporting */
endpointUrl?: string;
/** Additional headers for schema reporting requests */
headers?: { [key: string]: string };
}Plugin for HTTP cache control and response caching.
/**
* Enable cache control functionality
* @param options - Configuration options for cache control
* @returns Plugin instance for cache control
*/
function ApolloServerPluginCacheControl(
options?: ApolloServerPluginCacheControlOptions
): ApolloServerPlugin;
/**
* Disable cache control (explicit opt-out)
* @returns Plugin instance that disables cache control
*/
function ApolloServerPluginCacheControlDisabled(): ApolloServerPlugin;
interface ApolloServerPluginCacheControlOptions {
/** Default max age for cacheable responses (in seconds) */
defaultMaxAge?: number;
/** Calculate cache hints from schema */
calculateHttpHeaders?: boolean | 'if-cacheable';
/** Strip cache control extensions from response */
stripFormattedExtensions?: boolean;
}Cache Control Examples:
import {
ApolloServerBase,
ApolloServerPluginCacheControl
} from "apollo-server-core";
// Enable cache control with default max age
const server = new ApolloServerBase({
typeDefs,
resolvers,
plugins: [
ApolloServerPluginCacheControl({
defaultMaxAge: 300, // 5 minutes
calculateHttpHeaders: true,
}),
],
});
// In your schema, use cache control directives
const typeDefs = gql`
type Query {
posts: [Post!]! @cacheControl(maxAge: 60)
user(id: ID!): User @cacheControl(maxAge: 300, scope: PRIVATE)
}
type Post @cacheControl(maxAge: 300) {
id: ID!
title: String!
author: User!
}
`;Plugin for including execution traces in GraphQL responses.
/**
* Enable inline traces in GraphQL responses
* @param options - Configuration options for inline traces
* @returns Plugin instance for inline traces
*/
function ApolloServerPluginInlineTrace(
options?: ApolloServerPluginInlineTraceOptions
): ApolloServerPlugin;
/**
* Disable inline traces (explicit opt-out)
* @returns Plugin instance that disables inline traces
*/
function ApolloServerPluginInlineTraceDisabled(): ApolloServerPlugin;
interface ApolloServerPluginInlineTraceOptions {
/** Include trace for this request */
includeTrace?: (requestContext: GraphQLRequestContext) => ValueOrPromise<boolean>;
}Plugin for gracefully draining HTTP servers during shutdown.
/**
* Enable HTTP server draining during shutdown
* @param options - Configuration options for server draining
* @returns Plugin instance for HTTP server draining
*/
function ApolloServerPluginDrainHttpServer(
options: ApolloServerPluginDrainHttpServerOptions
): ApolloServerPlugin;
interface ApolloServerPluginDrainHttpServerOptions {
/** HTTP server instance to drain */
httpServer: http.Server | https.Server;
/** Grace period before force closing (in milliseconds) */
gracefulShutdownTimeout?: number;
}HTTP Drain Example:
import http from 'http';
import {
ApolloServerBase,
ApolloServerPluginDrainHttpServer
} from "apollo-server-core";
const httpServer = http.createServer();
const server = new ApolloServerBase({
typeDefs,
resolvers,
plugins: [
ApolloServerPluginDrainHttpServer({
httpServer,
gracefulShutdownTimeout: 10000, // 10 seconds
}),
],
});
// Graceful shutdown
process.on('SIGTERM', async () => {
await server.stop(); // This will drain the HTTP server
});Plugins for customizing the Apollo Server landing page.
/**
* Disable landing page completely
* @returns Plugin instance that disables landing page
*/
function ApolloServerPluginLandingPageDisabled(): ApolloServerPlugin;
/**
* Local development landing page with GraphQL Playground
* @param options - Configuration options for local landing page
* @returns Plugin instance for local development landing page
*/
function ApolloServerPluginLandingPageLocalDefault(
options?: ApolloServerPluginLandingPageLocalDefaultOptions
): ApolloServerPlugin;
/**
* Production landing page with Apollo Studio integration
* @param options - Configuration options for production landing page
* @returns Plugin instance for production landing page
*/
function ApolloServerPluginLandingPageProductionDefault(
options?: ApolloServerPluginLandingPageProductionDefaultOptions
): ApolloServerPlugin;
/**
* GraphQL Playground landing page
* @param options - Configuration options for GraphQL Playground
* @returns Plugin instance for GraphQL Playground
*/
function ApolloServerPluginLandingPageGraphQLPlayground(
options?: ApolloServerPluginLandingPageGraphQLPlaygroundOptions
): ApolloServerPlugin;
interface ApolloServerPluginLandingPageLocalDefaultOptions {
/** Footer content for the landing page */
footer?: boolean;
/** Custom document title */
document?: string;
/** Embed Apollo Studio */
embed?: boolean;
}
interface ApolloServerPluginLandingPageProductionDefaultOptions {
/** GraphQL endpoint URL for Apollo Studio */
graphRef?: string;
/** Footer content for the landing page */
footer?: boolean;
/** Embed Apollo Studio */
embed?: boolean;
}
interface ApolloServerPluginLandingPageGraphQLPlaygroundOptions {
/** GraphQL endpoint URL */
endpoint?: string;
/** Subscription endpoint URL */
subscriptionEndpoint?: string;
/** Default query to show in playground */
query?: string;
/** Default variables to show in playground */
variables?: Record<string, any>;
/** Default headers to show in playground */
headers?: Record<string, string>;
/** Playground settings */
settings?: {
'editor.cursorShape'?: 'line' | 'block' | 'underline';
'editor.fontFamily'?: string;
'editor.fontSize'?: number;
'editor.reuseHeaders'?: boolean;
'editor.theme'?: 'dark' | 'light';
'general.betaUpdates'?: boolean;
'prettier.printWidth'?: number;
'prettier.tabWidth'?: number;
'prettier.useTabs'?: boolean;
'request.credentials'?: 'omit' | 'include' | 'same-origin';
'schema.disableComments'?: boolean;
'schema.polling.enable'?: boolean;
'schema.polling.endpointFilter'?: string;
'schema.polling.interval'?: number;
'tracing.hideTracingResponse'?: boolean;
};
}Landing Page Examples:
import {
ApolloServerBase,
ApolloServerPluginLandingPageLocalDefault,
ApolloServerPluginLandingPageProductionDefault,
ApolloServerPluginLandingPageGraphQLPlayground,
} from "apollo-server-core";
// Local development with default landing page
const server = new ApolloServerBase({
typeDefs,
resolvers,
plugins: [
process.env.NODE_ENV === 'production'
? ApolloServerPluginLandingPageProductionDefault()
: ApolloServerPluginLandingPageLocalDefault(),
],
});
// Custom GraphQL Playground
const server = new ApolloServerBase({
typeDefs,
resolvers,
plugins: [
ApolloServerPluginLandingPageGraphQLPlayground({
settings: {
'editor.theme': 'dark',
'editor.fontSize': 14,
},
}),
],
});Core types for the plugin system that all plugins implement.
type PluginDefinition = ApolloServerPlugin | (() => ApolloServerPlugin);
interface ApolloServerPlugin {
/** Server lifecycle hooks */
serverWillStart?(): ValueOrPromise<GraphQLServerListener | void>;
/** Request lifecycle hooks */
requestDidStart?(): GraphQLRequestListener | void;
}
interface GraphQLServerListener {
serverWillStop?(): ValueOrPromise<void>;
}
interface GraphQLRequestListener {
didResolveOperation?(
requestContext: GraphQLRequestContext
): ValueOrPromise<void>;
didEncounterErrors?(
requestContext: GraphQLRequestContext
): ValueOrPromise<void>;
willSendResponse?(
requestContext: GraphQLRequestContext
): ValueOrPromise<void>;
}