graphql-apollo-server

Build production GraphQL servers with Apollo Server, plugins, and federation

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "graphql-apollo-server" with this command: npx skills add pluginagentmarketplace/custom-plugin-graphql/pluginagentmarketplace-custom-plugin-graphql-graphql-apollo-server

Apollo Server Skill

Deploy production-ready GraphQL APIs

Overview

Learn to build scalable GraphQL servers with Apollo Server 4, including middleware integration, custom plugins, federation, and production best practices.


Quick Reference

FeaturePackagePurpose
Server@apollo/serverCore server
Express@apollo/server/express4Express integration
Plugins@apollo/server/plugin/*Extensibility
Federation@apollo/subgraphMicroservices

Core Setup

1. Basic Server (Express)

import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import express from 'express';
import http from 'http';
import cors from 'cors';

interface Context {
  user: User | null;
  dataSources: DataSources;
}

async function startServer() {
  const app = express();
  const httpServer = http.createServer(app);

  const server = new ApolloServer<Context>({
    typeDefs,
    resolvers,
    plugins: [
      // Graceful shutdown
      ApolloServerPluginDrainHttpServer({ httpServer }),
    ],
  });

  await server.start();

  app.use(
    '/graphql',
    cors({ origin: ['http://localhost:3000'], credentials: true }),
    express.json(),
    expressMiddleware(server, {
      context: async ({ req }) => ({
        user: await getUser(req),
        dataSources: createDataSources(),
      }),
    }),
  );

  httpServer.listen(4000, () => {
    console.log('Server ready at http://localhost:4000/graphql');
  });
}

2. Production Configuration

const server = new ApolloServer<Context>({
  typeDefs,
  resolvers,

  // Error formatting
  formatError: (error) => {
    console.error('GraphQL Error:', error);

    // Hide internal errors in production
    if (process.env.NODE_ENV === 'production') {
      if (error.extensions?.code === 'INTERNAL_SERVER_ERROR') {
        return { message: 'Internal error', extensions: { code: 'INTERNAL_ERROR' } };
      }
    }
    return error;
  },

  // Disable introspection in production
  introspection: process.env.NODE_ENV !== 'production',

  plugins: [
    ApolloServerPluginDrainHttpServer({ httpServer }),
    loggingPlugin,
    complexityPlugin,
  ],
});

3. Custom Plugins

import { ApolloServerPlugin } from '@apollo/server';

// Logging plugin
const loggingPlugin: ApolloServerPlugin<Context> = {
  async requestDidStart({ request, contextValue }) {
    const start = Date.now();
    console.log('Request:', request.operationName);

    return {
      async willSendResponse() {
        console.log(`Completed in ${Date.now() - start}ms`);
      },

      async didEncounterErrors({ errors }) {
        errors.forEach(e => console.error('Error:', e.message));
      },
    };
  },
};

// Query complexity plugin
import { getComplexity, simpleEstimator } from 'graphql-query-complexity';

const complexityPlugin: ApolloServerPlugin<Context> = {
  async requestDidStart() {
    return {
      async didResolveOperation({ schema, document, request }) {
        const complexity = getComplexity({
          schema,
          query: document,
          variables: request.variables,
          estimators: [simpleEstimator({ defaultComplexity: 1 })],
        });

        if (complexity > 1000) {
          throw new GraphQLError('Query too complex');
        }
      },
    };
  },
};

4. Federation (Subgraph)

import { buildSubgraphSchema } from '@apollo/subgraph';
import { gql } from 'graphql-tag';

const typeDefs = gql`
  extend schema
    @link(url: "https://specs.apollo.dev/federation/v2.0",
          import: ["@key", "@shareable", "@external"])

  type Query {
    user(id: ID!): User
  }

  type User @key(fields: "id") {
    id: ID!
    name: String!
    email: String!
  }
`;

const resolvers = {
  Query: {
    user: (_, { id }) => users.find(u => u.id === id),
  },
  User: {
    __resolveReference: (user) => users.find(u => u.id === user.id),
  },
};

const server = new ApolloServer({
  schema: buildSubgraphSchema({ typeDefs, resolvers }),
});

5. Response Caching

import responseCachePlugin from '@apollo/server-plugin-response-cache';

const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [
    responseCachePlugin({
      // Cache key includes user ID for personalized data
      sessionId: ({ contextValue }) => contextValue.user?.id || null,
    }),
  ],
});

// Schema hints
const typeDefs = gql`
  type Query {
    # Cache for 1 hour
    popularPosts: [Post!]! @cacheControl(maxAge: 3600)

    # Private, user-specific
    me: User @cacheControl(maxAge: 0, scope: PRIVATE)
  }
`;

6. Health Checks

// Health endpoint
app.get('/health', async (req, res) => {
  const checks = {
    server: 'healthy',
    database: await checkDb(),
    redis: await checkRedis(),
  };

  const healthy = Object.values(checks).every(c => c === 'healthy');
  res.status(healthy ? 200 : 503).json(checks);
});

// Readiness endpoint
app.get('/ready', (req, res) => {
  res.status(serverReady ? 200 : 503).json({ ready: serverReady });
});

Troubleshooting

IssueCauseSolution
CORS errorsMissing middlewareAdd cors() before expressMiddleware
503 on shutdownNo drainAdd DrainHttpServer plugin
Memory leakGlobal loadersCreate per-request
Slow startupLarge schemaUse schema caching

Debug Commands

# Test server
curl http://localhost:4000/health

# Test GraphQL
curl -X POST http://localhost:4000/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __typename }"}'

# Introspection
curl -X POST http://localhost:4000/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name } } }"}'

Usage

Skill("graphql-apollo-server")

Related Skills

  • graphql-resolvers - Resolver implementation
  • graphql-security - Security configuration
  • graphql-codegen - Type generation

Related Agent

  • 04-graphql-apollo-server - For detailed guidance

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

graphql-fundamentals

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

graphql-schema-design

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

graphql-resolvers

No summary provided by upstream source.

Repository SourceNeeds Review