Learning GraphQL: A Practical Approach
Tags: graphql, express
Published: 2024-01-10 10:42:43

In this article, we will embark on a practical journey to learn GraphQL. We will set up a simple Apollo Server that serves static data using GraphQL. This approach allows us to focus on the core concepts of GraphQL without the added complexity of a database. 

We will start by setting up our project and installing the necessary dependencies. Then, we will define our GraphQL schema and resolvers. Finally, we will start our server and test it by running some GraphQL queries. 

This hands-on approach is designed to provide a solid foundation in GraphQL. By the end of this article, you will have a working Apollo Server and a clear understanding of how to define and use GraphQL schemas and resolvers.  Let's dive in and start learning GraphQL!

---

## Step 1: Setting up the project

First, we need to set up our project and install the necessary dependencies. We will be using npm (Node Package Manager) to manage our dependencies.

```
npm init -y
npm install express graphql apollo-server
```
In your package.json file, you should have the following dependencies:

```
"dependencies": {
  "apollo-server": "^3.13.0",
  "graphql": "^16.8.1",
  "express": "~4.16.1"
}
```

If you don't have these dependencies, you can install them by running the following command in your terminal:
`npm install apollo-server graphql`

## Step 2: Defining the GraphQL schema

Next, we need to define our GraphQL schema. The schema defines the types of data that can be queried through our GraphQL server. In our case, we have a Book type, Author type, and a Query type in our schema/schema.js file:

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

const typeDefs = gql`
  type Book {
    title: String!
    author: Author!
  }

  type Author {
    name: String!
    books: [Book]
  }

  type Query {
    books: [Book]
    authors: [Author]
  }
`;

module.exports = typeDefs;
```

The Book type represents a book with a title and an author. The Author type represents an author with a name and a list of books. The Query type defines the queries that can be made to our server. In this case, we have a **books query** that returns an array of books and an **authors query** that returns an array of authors.  

## Step 3: Defining the resolvers

After defining our schema, we need to define our resolvers. The resolvers specify how the data for each type is fetched. In our resolvers/resolvers.js file, we have defined a resolver for the books query and the **authors query**:

```
const authors = [
  {
    name: 'J.K. Rowling',
    books: [
      {
        title: 'Harry Potter and the Chamber of Secrets',
      },
      {
        title: 'Harry Potter and the Philosopher\'s Stone',
      },
    ],
  },
  {
    name: 'Michael Crichton',
    books: [
      {
        title: 'Jurassic Park',
      },
      {
        title: 'The Lost World',
      },
    ],
  },
];

const resolvers = {
  Query: {
    books: () => authors.flatMap(author => author.books),
    authors: () => authors,
  },
  Book: {
    author: (book) => authors.find(author => author.books.some(b => b.title === book.title)),
  },
  Author: {
    books: (author) => author.books,
  },
};

module.exports = resolvers;
```
The books resolver returns an array of static book data.

## Step 4: Starting the server

Finally, we need to start our server. We do this in our app.js file:

```
const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema/schema');
const resolvers = require('./resolvers/resolvers');

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

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

We create an instance of ApolloServer with our schema and resolvers, and then start the server by calling the listen method. The server will be listening on the default port (4000) and will log a message to the console when it's ready.

![ready log message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flcqhbnwacszoqj7xf24.png)

That's it! You now have a working Apollo Server that serves static data using GraphQL. You can test your server by opening your browser and navigating to `http://localhost:4000`. This will open the Apollo Server playground, where you can run GraphQL queries to test your server.  Here are some example queries you can run:

```
# Query for all books with their authors
query {
  books {
    title
    author {
      name
    }
  }
}

# Query for all authors with their books
query {
  authors {
    name
    books {
      title
    }
  }
}
```

## Here is the result:

![Query for all books with their authors](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uuojeypdigknpl1fov2l.png)


![Query for all authors with their books](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h4h2jy1rc43d8rwkh9fn.png)