Building a Beginner-Friendly GraphQL API with Node.js, Apollo Server, and Express

Building a Beginner-Friendly GraphQL API with Node.js, Apollo Server, and Express

Play this article

Introduction

GraphQL is a query language and runtime for APIs that was developed by Facebook. Unlike traditional REST APIs, GraphQL APIs allow clients to request only the data they need, and provide a flexible way for clients to specify complex queries with nested fields, filters, and sorting.

In this article, we'll walk through building a GraphQL API with Node.js and Apollo Server. We'll cover the building blocks of a GraphQL API, including the schema, mutation, and resolver, and show you how to define a simple API that returns a list of users and allows you to create new users.

Building Blocks of a GraphQL API

GraphQL APIs have several key building blocks::

  • Schema: The schema defines the types of data that can be queried and the operations that can be performed on that data.

  • Query: The query is a request for specific data from the API. It defines the fields and parameters that the client wants to receive.

  • Mutation: A mutation is an operation that changes data on the server. Like queries, mutations define specific fields and parameters.

  • Resolver: A resolver is a function that retrieves the data requested in a query or mutation. Resolvers are responsible for executing the logic required to fetch the requested data.

  • Type: A type defines the structure of data that can be queried or mutated. Types can be objects, scalars, interfaces, or unions.

  • Field: A field is a unit of data that can be queried or mutated. Fields are defined within types and can be scalar values, objects, or lists of other types.

  • Argument: An argument is a parameter passed to a query or mutation. Arguments can be used to filter or sort data, or to specify the exact data to be returned.

  • Subscription: A subscription is a real-time connection between the client and server that allows the client to receive updates when the server data changes.

These building blocks are used together to create a flexible and powerful API that can efficiently retrieve and modify data.

Setting Up Node.js and Apollo Server

Before we start building our GraphQL API, we need to set up our development environment. We'll be using Node.js and Apollo Server to create our API.

To get started, make sure you have Node.js installed on your machine. You can download the latest version from the official Node.js website.

Next, create a new directory for your project and navigate to it in your terminal. Run the following command to initialize a new Node.js project:

npm init -y

This will create a new package.json file for your project. Next, we need to install the required dependencies. Run the following command:

npm install apollo-server-express express jsonfile

This installs Apollo Server, Express, and jsonfile, which we'll be using in our code snippet.

We will create an in-memory json file called data.json

{
    "users": [
        { "id": 1, "name": "Emma", "age": 60 },
        { "id": 2, "name": "Emediong", "age": 30 },
        { "id": 3, "name": "Charles", "age": 35 }
    ]
}

Defining the GraphQL Schema

The first step in building our GraphQL API is defining the schema. The schema defines the types of data that can be queried, and the operations that can be performed on that data.

Create a new file called schema.js and add the following code:

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

const typeDefs = gql`
    type Query {
        users: [User!]!
    }

    type Mutation {
        createUser(name: String!, age: Int!): User!
    }

    type User {
        id: ID!
        name: String!
        age: Int!
    }
`;

module.exports = typeDefs;

This defines a User type, which has an id, name, and age field. We also define a Query type, which has a users field that returns an array of User objects. Finally, we define a Mutation type, which has a createUser field that creates a new User object.

Creating GraphQL Resolvers

The next step is to create resolvers for our GraphQL API. Resolvers are functions that are responsible for fetching the data for a particular field in the schema.

Create a new file called resolvers.js and add the following code:

const jsonfile = require('jsonfile');
const data = jsonfile.readFileSync('data.json');

const resolvers = {
    Query: {
        users: () => data.users,
    },
    Mutation: {
        createUser: (parent, args) => {
            const id = data.users.length + 1;
            const newUser = { id, ...args };
            data.users.push(newUser);
            jsonfile.writeFileSync('data.json', data);
            return newUser;
        },
    },
};

module.exports = resolvers;

Resolvers are functions that execute the logic for each field defined in the schema. In the example above, the resolvers object contains two functions: users and createUser. These functions correspond to the users and createUser fields defined in the schema.

The users resolver simply returns the users array from the data object.

The createUser resolver takes two arguments: parent and args. The parent argument represents the parent object, which is not used in this example. The args argument represents the arguments passed to the createUser mutation. The resolver generates a new ID for the user, adds the user to the data object, and returns the new user.

Testing Your GraphQL API

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

const app = express();

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

async function startServer() {
  await server.start();
  console.log('Server started on http://localhost:3000/graphql');
}

startServer().then(() => {
  server.applyMiddleware({ app });

  app.listen(3000, () => {
    console.log('Server listening on port 3000');
  });
}).catch((err) => {
  console.error(err);
});

This sets up an Express app, creates an ApolloServer instance with our schema and resolvers, and starts the server on port 3000.

To test our GraphQL API, open a web browser and go to `localhost:3000/graphql`. This will open the Apollo Studio GraphQL playground, where you can test your API.

In the left pane, you'll see the documentation for your schema. You can use the right pane to enter queries and mutations and see the results.

To test the createUser mutation, enter the following in the right pane:

mutation {
  createUser(name: "John Doe", age: 25) {
    id
    name
    age
  }
}

This will create a new User object with the name "John Doe" and age 25, and return the id, name, and age of the new user.

To test the users query, enter the following in the right pane:

query {
  users {
    id
    name
    age
  }
}

This will return an array of all the User objects in the data file.

Congratulations, you've just built and tested your first GraphQL API with Node.js and Apollo Server!

Conclusion

In this article, we walked through building a GraphQL API with Node.js and Apollo Server. We covered the basics of GraphQL, set up our development environment, defined the schema, created resolvers, and tested our API using the Apollo Studio GraphQL playground.

GraphQL is a powerful tool for building APIs that are flexible, efficient, and easy to use. With Node.js and Apollo Server, it's easy to get started building your own GraphQL API.

Did you find this article valuable?

Support Edet Asuquo by becoming a sponsor. Any amount is appreciated!