How to use Apollo Server in Node.js

Apollo Server is the most popular GraphQL server implementation for Node.js, providing powerful tools for building type-safe, efficient APIs with excellent developer experience. With over 25 years of backend development experience and as the creator of CoreUI, I’ve used Apollo Server extensively for building scalable GraphQL APIs. The most effective approach is setting up Apollo Server with clear schema definitions, organized resolvers, and proper error handling. This provides a robust GraphQL API foundation with built-in features like caching, subscriptions, and excellent debugging capabilities.

Use Apollo Server with Express to create a powerful GraphQL API with schema definition, resolvers, and built-in development tools.

const { ApolloServer } = require('apollo-server-express')
const { gql } = require('apollo-server-express')
const express = require('express')

// GraphQL schema definition
const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
    posts: [Post]
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    author: User!
    createdAt: String!
  }

  type Query {
    users: [User]
    user(id: ID!): User
    posts: [Post]
    post(id: ID!): Post
  }

  type Mutation {
    createUser(name: String!, email: String!): User
    createPost(title: String!, content: String!, authorId: ID!): Post
    updatePost(id: ID!, title: String, content: String): Post
    deletePost(id: ID!): Boolean
  }

  type Subscription {
    postAdded: Post
  }
`

// Sample data (use database in production)
const users = [
  { id: '1', name: 'John Doe', email: '[email protected]' },
  { id: '2', name: 'Jane Smith', email: '[email protected]' }
]

const posts = [
  { id: '1', title: 'GraphQL Basics', content: 'Learning GraphQL...', authorId: '1', createdAt: '2025-11-26' }
]

// Resolvers
const resolvers = {
  Query: {
    users: () => users,
    user: (_, { id }) => users.find(user => user.id === id),
    posts: () => posts,
    post: (_, { id }) => posts.find(post => post.id === id)
  },

  Mutation: {
    createUser: (_, { name, email }) => {
      const newUser = {
        id: String(users.length + 1),
        name,
        email
      }
      users.push(newUser)
      return newUser
    },

    createPost: (_, { title, content, authorId }, { pubsub }) => {
      const newPost = {
        id: String(posts.length + 1),
        title,
        content,
        authorId,
        createdAt: new Date().toISOString()
      }
      posts.push(newPost)

      // Publish subscription
      pubsub.publish('POST_ADDED', { postAdded: newPost })

      return newPost
    }
  },

  // Field resolvers
  User: {
    posts: (user) => posts.filter(post => post.authorId === user.id)
  },

  Post: {
    author: (post) => users.find(user => user.id === post.authorId)
  }
}

async function startServer() {
  const app = express()

  const server = new ApolloServer({
    typeDefs,
    resolvers,
    context: ({ req }) => {
      // Add authentication, database connections, etc.
      return {
        user: req.user, // from auth middleware
        // db: database connection
      }
    },
    introspection: true,
    playground: true
  })

  await server.start()
  server.applyMiddleware({ app, path: '/graphql' })

  app.listen(4000, () => {
    console.log(`Server ready at http://localhost:4000${server.graphqlPath}`)
    console.log(`GraphQL Playground available for queries and testing`)
  })
}

startServer()

This Apollo Server setup provides a complete GraphQL API with type definitions, resolvers for queries and mutations, and field resolvers for related data. The context function allows injecting dependencies like authentication and database connections. Apollo Server includes GraphQL Playground for interactive API testing and exploration.

Best Practice Note:

This Apollo Server pattern is used in CoreUI’s advanced backend templates for flexible, type-safe APIs. Always implement proper authentication, input validation, and rate limiting for production deployments, and consider using DataLoader for efficient database queries.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author