Introduction to GraphQL and Its Advantages
GraphQL is a query language for APIs developed by Facebook. Unlike REST, where each endpoint returns a fixed data structure, GraphQL allows the client to request only the needed fields. This makes the API more flexible and efficient.
In this tutorial, we will create a simple GraphQL server using Node.js with the Apollo Server library, set up a schema, and implement queries and mutations. You will learn:
- How to install and configure Apollo Server
- How to define a schema with data types
- How to write resolvers for queries and mutations
- How to test the API via GraphQL Playground
To get started, you will need Node.js (version 16+) and a basic understanding of JavaScript. Let's begin!
Step 1: Project Setup and Installing Dependencies
Create a new directory for the project and initialize package.json:
mkdir graphql-tutorialcd graphql-tutorialnpm init -yInstall the required packages:
npm install apollo-server graphqlThe apollo-server package provides a ready-to-use HTTP server for GraphQL, and graphql is the core for working with schemas and queries.
Step 2: Creating a Basic Schema and Resolvers
Create a file index.js and import Apollo Server:
const { ApolloServer, gql } = require('apollo-server');
// In-memory data (simulating a database)const books = [ { id: '1', title: 'War and Peace', author: 'Leo Tolstoy', year: 1869 }, { id: '2', title: 'Crime and Punishment', author: 'Fyodor Dostoevsky', year: 1866 }, { id: '3', title: 'The Master and Margarita', author: 'Mikhail Bulgakov', year: 1967 }];Now define the schema using the gql tag:
const typeDefs = gql` type Book { id: ID! title: String! author: String! year: Int }
type Query { books: [Book] book(id: ID!): Book }
type Mutation { addBook(title: String!, author: String!, year: Int): Book }`;Create resolvers — functions that return data for each query field:
const resolvers = { Query: { books: () => books, book: (parent, args) => books.find(book => book.id === args.id) }, Mutation: { addBook: (parent, args) => { const newBook = { id: String(books.length + 1), title: args.title, author: args.author, year: args.year }; books.push(newBook); return newBook; } }};Step 3: Starting the Server and Testing
Create an instance of the server and start it:
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => { console.log(`🚀 Server ready at: ${url}`);});Start the server with the command node index.js. By default, Apollo Server runs on port 4000 and opens GraphQL Playground — an interactive environment for testing queries.
Try executing a simple query:
query { books { title author }}The response should contain an array of books with the selected fields:
{ "data": { "books": [ { "title": "War and Peace", "author": "Leo Tolstoy" }, { "title": "Crime and Punishment", "author": "Fyodor Dostoevsky" }, { "title": "The Master and Margarita", "author": "Mikhail Bulgakov" } ] }}Now let's test a mutation to add a new book:
mutation { addBook(title: "Anna Karenina", author: "Leo Tolstoy", year: 1877) { id title author }}After executing the mutation, the server will return the new book object with an assigned ID.