From harness-claude
Configures Apollo Server 4 with plugins, context, data sources, and integrations for Express, Fastify, standalone. Guides new GraphQL API setup, v3 migration, auth/logging, production config.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Configure and run Apollo Server with plugins, context, data sources, and framework integrations
Guides building GraphQL servers with Apollo Server 5.x including project setup, resolvers, schemas, authentication, plugins, data sources, and troubleshooting errors or performance.
Provides patterns for building GraphQL APIs with Apollo Server, covering schema design, resolvers, data sources, federation, error handling, and production setup.
Builds GraphQL APIs with schema design, resolvers, DataLoader for N+1 prevention, error handling, and optimizations using Apollo Server (JS) or Graphene (Python). Useful for flexible queries, REST migrations, or subscriptions.
Share bugs, ideas, or general feedback.
Configure and run Apollo Server with plugins, context, data sources, and framework integrations
@apollo/server with the appropriate integration package.import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import express from 'express';
import cors from 'cors';
const app = express();
const server = new ApolloServer({ typeDefs, resolvers });
await server.start();
app.use(
'/graphql',
cors(),
express.json(),
expressMiddleware(server, {
context: async ({ req }) => ({
currentUser: await authenticate(req.headers.authorization),
}),
})
);
app.listen(4000);
Build the context object in the integration, not in ApolloServer. AS4 moved context creation to the framework integration layer. The context function receives the framework-specific request object.
Use plugins for cross-cutting concerns. Plugins hook into the request lifecycle — use them for logging, APM, caching, and error tracking instead of middleware.
const loggingPlugin: ApolloServerPlugin<Context> = {
async requestDidStart({ request }) {
const start = Date.now();
return {
async willSendResponse({ response }) {
const duration = Date.now() - start;
logger.info({ operationName: request.operationName, duration });
},
async didEncounterErrors({ errors }) {
errors.forEach((err) => logger.error(err));
},
};
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [loggingPlugin],
});
import { ApolloServerPluginLandingPageDisabled } from '@apollo/server/plugin/disabled';
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: process.env.NODE_ENV !== 'production',
plugins: [
process.env.NODE_ENV === 'production'
? ApolloServerPluginLandingPageDisabled()
: ApolloServerPluginLandingPageLocalDefault(),
],
});
class UserDataSource {
constructor(
private db: Database,
private loader: DataLoader<string, User>
) {}
async findById(id: string): Promise<User | null> {
return this.loader.load(id);
}
async create(input: CreateUserInput): Promise<User> {
const user = await this.db.users.insert(input);
this.loader.prime(user.id, user);
return user;
}
}
formatError to sanitize errors before sending to clients. Strip stack traces, internal messages, and sensitive data from error responses in production.const server = new ApolloServer({
typeDefs,
resolvers,
formatError: (formattedError, error) => {
if (process.env.NODE_ENV === 'production') {
delete formattedError.extensions?.stacktrace;
}
return formattedError;
},
});
Call server.start() before applying middleware. AS4 requires explicit startup. This validates the schema and initializes plugins before the server accepts requests.
Use server.stop() for graceful shutdown. Hook into process signals to drain in-flight requests before exiting.
const shutdown = async () => {
await server.stop();
process.exit(0);
};
process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);
Apollo Server 3 to 4 migration: AS4 removes apollo-server-express in favor of @apollo/server + expressMiddleware. The constructor no longer accepts context — pass it to the integration. dataSources config is removed — create data sources in the context function. plugins and formatError remain on the constructor.
Plugin lifecycle hooks: serverWillStart, requestDidStart (returns per-request hooks: didResolveSource, didResolveOperation, responseForOperation, executionDidStart, willSendResponse, didEncounterErrors). Use the most specific hook for your use case.
Performance tuning:
@cacheControl directives for CDN-level cachingallowBatchedHttpRequests: true for client-side query batchingHealth checks: AS4 does not include a built-in health check endpoint. Add one in your framework layer: app.get('/health', (_, res) => res.sendStatus(200)).
CSRF prevention: AS4 includes CSRF prevention by default — it requires a non-empty Content-Type header or a custom header like Apollo-Require-Preflight. Do not disable this in production.
https://www.apollographql.com/docs/apollo-server/