How to Set Up a GraphQL Server with Apollo and Node.js: Step-by-Step Guide

14/07/2025

How to Set Up a GraphQL Server with Apollo and Node.js: Step-by-Step Guide

Learn how to set up a GraphQL server using Apollo Server and Node.js. This beginner-friendly tutorial covers schema definition, resolvers, and query handling with practical examples.

Setup GraphQL Server with Apollo and Node.js

Build powerful and flexible APIs with GraphQL and Apollo Server.

In the evolving landscape of API development, GraphQL has emerged as a powerful alternative to traditional REST APIs. It allows clients to request exactly the data they need, no more and no less, solving common problems like over-fetching and under-fetching. When building GraphQL servers with Node.js, **Apollo Server** is a popular, production-ready choice that simplifies the process significantly. This guide will walk you through setting up a basic GraphQL server using Node.js and Apollo Server, covering schema definition, resolvers, and integration with Express.js.

Why GraphQL?

  • Efficient Data Fetching: Clients request only what they need, reducing network payload.
  • Single Endpoint: All requests go to a single endpoint, simplifying API management.
  • Strongly Typed Schema: Provides a clear contract between client and server, enabling better tooling and validation.
  • Reduced Round Trips: Fetch related data in a single request, avoiding multiple API calls.
  • Evolving APIs: Easily add new fields and types to your API without breaking existing clients.

Prerequisites

  • Node.js and npm (or yarn) installed.
  • Basic understanding of JavaScript and Node.js.
  • Familiarity with Express.js concepts (optional but helpful).

1. Project Setup

Start by creating a new Node.js project and installing the necessary packages:

# Create a new project directory
mkdir my-graphql-server
cd my-graphql-server

# Initialize npm project
npm init -y

# Install dependencies
npm install express @apollo/server graphql
  • `express`: Our web framework for Node.js.
  • `@apollo/server`: The core Apollo Server library.
  • `graphql`: The reference implementation of GraphQL, required by Apollo Server.

2. Define Your GraphQL Schema (Type Definitions)

The schema defines the structure of your data and the operations clients can perform. GraphQL uses its own Schema Definition Language (SDL). Create a file named `schema.js` (or `typeDefs.js`).

// schema.js
const { gql } = require('apollo-server-express'); // Or from '@apollo/server' if not using express-specific integration

// Define your GraphQL schema using GraphQL SDL
const typeDefs = gql`
  # Define a 'Book' type
  type Book {
    id: ID!
    title: String!
    author: String!
    year: Int
  }

  # Define the Query type (for reading data)
  type Query {
    books: [Book] # Get a list of all books
    book(id: ID!): Book # Get a single book by ID
  }

  # Define the Mutation type (for writing/modifying data)
  type Mutation {
    addBook(title: String!, author: String!, year: Int): Book
    updateBook(id: ID!, title: String, author: String, year: Int): Book
    deleteBook(id: ID!): String
  }
`;

module.exports = typeDefs;

3. Implement Resolvers

Resolvers are functions that tell GraphQL how to fetch the data for a particular type or field in your schema. They map the schema fields to actual data sources (e.g., databases, external APIs, or in-memory data). Create a file named `resolvers.js`.

// resolvers.js
// In-memory data for demonstration (replace with database calls in a real app)
let books = [
  { id: '1', title: 'The Great Gatsby', author: 'F. Scott Fitzgerald', year: 1925 },
  { id: '2', title: 'To Kill a Mockingbird', author: 'Harper Lee', year: 1960 },
];

const resolvers = {
  Query: {
    books: () => books, // Returns all books
    book: (parent, { id }) => books.find(book => book.id === id), // Finds a book by ID
  },
  Mutation: {
    addBook: (parent, { title, author, year }) => {
      const newBook = { id: String(books.length + 1), title, author, year };
      books.push(newBook);
      return newBook;
    },
    updateBook: (parent, { id, title, author, year }) => {
      const bookIndex = books.findIndex(book => book.id === id);
      if (bookIndex === -1) return null; // Book not found

      const updatedBook = { ...books[bookIndex], title, author, year };
      books[bookIndex] = updatedBook;
      return updatedBook;
    },
    deleteBook: (parent, { id }) => {
      const initialLength = books.length;
      books = books.filter(book => book.id !== id);
      if (books.length < initialLength) {
        return `Book with ID ${id} deleted successfully.`;
      }
      return `Book with ID ${id} not found.`;
    },
  },
};

module.exports = resolvers;

4. Set Up Apollo Server with Express.js

Now, let's create our main server file, `server.js`, and integrate Apollo Server with Express.

// server.js
const express = require('express');
const { ApolloServer } = require('@apollo/server');
const { expressMiddleware } = require('@apollo/server/express4');
const { ApolloServerPluginDrainHttpServer } = require('@apollo/server/plugin/drainHttpServer');
const http = require('http');
const cors = require('cors');

const typeDefs = require('./schema');
const resolvers = require('./resolvers');

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

  // Set up Apollo Server
  const server = new ApolloServer({
    typeDefs,
    resolvers,
    plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
  });

  await server.start();

  // Apply Apollo Server middleware to Express
  app.use(
    '/graphql', // The path where your GraphQL API will be accessible
    cors(),
    express.json(),
    expressMiddleware(server),
  );

  // Start the HTTP server
  const PORT = process.env.PORT || 4000;
  await new Promise((resolve) => httpServer.listen({ port: PORT }, resolve));

  console.log(`🚀 Server ready at http://localhost:${PORT}/graphql`);
}

startApolloServer();

5. Running Your GraphQL Server

To start your server, run:

node server.js

You should see "🚀 Server ready at http://localhost:4000/graphql" in your console.

6. Testing Your API with Apollo Sandbox/Playground

Open your browser and navigate to `http://localhost:4000/graphql`. You will be greeted by Apollo Sandbox (or GraphQL Playground), a powerful in-browser IDE for interacting with your GraphQL API.

Example Queries:

# Get all books
query {
  books {
    id
    title
    author
    year
  }
}

# Get a single book by ID
query {
  book(id: "1") {
    title
    author
  }
}

# Add a new book
mutation {
  addBook(title: "The Hobbit", author: "J.R.R. Tolkien", year: 1937) {
    id
    title
    author
  }
}

# Update a book
mutation {
  updateBook(id: "1", title: "The Great Gatsby (Revised)", year: 2023) {
    title
    year
  }
}

# Delete a book
mutation {
  deleteBook(id: "2")
}

You've successfully set up a basic GraphQL server using Node.js and Apollo Server! This foundation allows you to build highly efficient and flexible APIs where clients have precise control over the data they receive. From here, you can expand your schema, integrate with databases (like MongoDB or PostgreSQL), implement authentication and authorization, and explore advanced features like subscriptions for real-time capabilities. GraphQL, combined with Apollo Server, provides a robust and developer-friendly ecosystem for modern API development.

GraphQL is transforming how APIs are built by allowing clients to request exactly the data they need. Combined with the simplicity of Node.js and the power of Apollo Server, you can create flexible and efficient APIs for modern applications.

In this step-by-step guide, you'll learn how to set up a GraphQL server with Apollo and Node.js. We'll walk through installing dependencies, defining your schema, writing resolvers, and running queries using the Apollo playground.

This tutorial is ideal for backend developers and JavaScript enthusiasts who want to go beyond REST and explore the benefits of GraphQL in real-world projects. Whether you're building a new API or modernizing an existing one, Apollo with Node.js offers a powerful combination for fast, reliable development.