Node.js8 min read

GraphQL with Apollo Server

Build GraphQL APIs with Apollo Server. Learn schema and resolvers.

Michael Torres
December 19, 2025
0.0k0

GraphQL with Apollo Server

GraphQL lets clients request exactly what they need. No over-fetching or under-fetching.

Setup

npm install apollo-server graphql

Basic Server

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

const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
  }
  
  type Query {
    users: [User!]!
    user(id: ID!): User
  }
`;

const users = [
  { id: '1', name: 'John', email: 'john@example.com' },
  { id: '2', name: 'Jane', email: 'jane@example.com' }
];

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

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

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});

Example Queries

query {
  users {
    id
    name
  }
}

query {
  user(id: "1") {
    name
    email
  }
}

Mutations

const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
  }
  
  type Query {
    users: [User!]!
  }
  
  type Mutation {
    createUser(name: String!, email: String!): User!
    deleteUser(id: ID!): Boolean!
  }
`;

const resolvers = {
  Query: {
    users: () => users
  },
  
  Mutation: {
    createUser: (parent, { name, email }) => {
      const user = {
        id: String(users.length + 1),
        name,
        email
      };
      users.push(user);
      return user;
    },
    
    deleteUser: (parent, { id }) => {
      const index = users.findIndex(u => u.id === id);
      if (index === -1) return false;
      users.splice(index, 1);
      return true;
    }
  }
};

Usage:

mutation {
  createUser(name: "Bob", email: "bob@example.com") {
    id
    name
  }
}

Real Example: Blog API

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

const typeDefs = gql`
  type Post {
    id: ID!
    title: String!
    content: String!
    author: User!
  }
  
  type User {
    id: ID!
    name: String!
    posts: [Post!]!
  }
  
  type Query {
    posts: [Post!]!
    post(id: ID!): Post
    users: [User!]!
  }
  
  type Mutation {
    createPost(title: String!, content: String!, authorId: ID!): Post!
  }
`;

const posts = [];
const users = [
  { id: '1', name: 'John' },
  { id: '2', name: 'Jane' }
];

const resolvers = {
  Query: {
    posts: () => posts,
    post: (parent, { id }) => posts.find(p => p.id === id),
    users: () => users
  },
  
  Mutation: {
    createPost: (parent, { title, content, authorId }) => {
      const post = {
        id: String(posts.length + 1),
        title,
        content,
        authorId
      };
      posts.push(post);
      return post;
    }
  },
  
  Post: {
    author: (post) => users.find(u => u.id === post.authorId)
  },
  
  User: {
    posts: (user) => posts.filter(p => p.authorId === user.id)
  }
};

const server = new ApolloServer({ typeDefs, resolvers });
server.listen();

With Express

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

const app = express();

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

await server.start();
server.applyMiddleware({ app });

app.listen(4000, () => {
  console.log(`Server ready at http://localhost:4000${server.graphqlPath}`);
});

Key Takeaway

GraphQL gives clients control over data shape. Define schema with types, implement resolvers for data fetching. Mutations for modifications. Apollo Server handles the complexity.

#Node.js#GraphQL#Apollo#API