Consuming a GraphQL API using Fetch and Async/Await

Consuming a GraphQL API using Fetch and Async/Await

graphql May 05, 2019

I was working on a small side project where I wanted to consume a GraphQL API. Before this, I hadn't worked with GraphQL much, other than configuring it which you can read about here. I knew there were libraries like Apolo, but I wanted to learn how to use a normal XHR request to consume a GraphQL API.

For the project I used React, but this will work with any JavaScript library/framework - provided you're using ES6.

Let's say you have a basic React component that is meant to load a list of movies within it's componentDidMount function.

import React from "react";

export class MovieList extends React.Component {
    state = {
        movieList: []
    };

    componentDidMount() {
        // Fetch movies from GraphQL endpoint here
    }
    
    render() {
        // render movies
    }
}

First, let's load up our GraphQL API into a playground to see what we will be querying. The playground I'll be using is FireQL.

In the playground, I'm going to use the searchMovies query that accepts a movie title and returns a list of movies. I've selected the follow fields to be returned:

searchMovies

The FireQL playground then gave me the following query:

{
    searchMovies(query: "endgame") {
        id
        title
        releaseDate
        overview
    }
}

Great! This is the query that we need to use within our React component.

First we will create a function that will accept a movie title and return the appropriate GraphQL string:

    getMoviesByTitleQuery = (movieTitle) => {
        return JSON.stringify({
            query: `
            {
                searchMovies(query: "${movieTitle}") {
                    id
                    title
                    releaseDate
                    overview
                }
            }
            `
        });
    };

Now we're gonna create a function that accepts a GraphQL query body and uses Fetch to retrieve the result from the API.

    performQuery = async(query) => {
        const res = await fetch("YourGraphQLEndpointHere/graphql", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            query
        });

        return await res.json();
    };

Finally, all we have to do now is use the two functions we created in one more function:

    queryMoviesByTitle = async(movieTitle) => {
        if (!movieTitle) {
            return [];
        }

        const movieQueryBody = this.getMovieSummaryByTitleQuery(movieTitle);
        const res = await this.performQuery(movieQueryBody);

        return res.data.searchMovies;
    };

Now use the queryMoviesByTitle function in componentDidMount and everything together will look like:

import React from "react";

export class MovieList extends React.Component {
    state = {
        movieList: []
    };

    componentDidMount() {
        const movieList = await this.queryMoviesByTitle(query);
        this.setState({ movieList });
    }
    
    queryMoviesByTitle = async(movieTitle) => {
        if (!movieTitle) {
            return [];
        }

        const movieQueryBody = this.getMoviesByTitleQuery(movieTitle);
        const res = await this.performQuery(movieQueryBody);

        return res.data.searchMovies;
    };
    
    getMoviesByTitleQuery = (movieTitle) => {
        return JSON.stringify({
            query: `
            {
                searchMovies(query: "${movieTitle}") {
                    id
                    title
                    releaseDate
                    overview
                }
            }
            `
        });
    };
    
    performQuery = async (query) => {
        const res = await fetch("YourGraphQLEndpointHere/graphql", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            query
        });

        return await res.json();
    };
    
    render() {
        const { movieList } = this.state;

        return (
            <div className="movie-list-container">
                {movieList.map(movie => (<div>{movie.title}</div>)}
            </div>
        );
    }
}

Great, now you have a function request to your GraphQL API and also some reusable functions that you can use for more of your GraphQL queries!

Tags

Harvey Delaney

Front End Engineer II at Amazon Web Services

Exclusive Usenet provider deals

Harvey's essential software engineering books

1

The Pragmatic Programmer: From Journeyman to Master

2

Clean Code: A Handbook of Agile Software Craftsmanship

3

Code Complete: A Practical Handbook of Software Construction

4

Design Patterns: Elements of Reusable Object-Oriented Software

Harvey is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com
Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.