Open In App

Consuming a GraphQL API using fetch – React Client

Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will learn to develop a React application, which will fetch the data from a public GraphQL API using Fetch. We will use The Movie Database Wrapper ( TMDB ) API to fetch the shows available with name/keyword. You can find the API reference and source code links at the end of this article.

Before moving onto the development part, to initialize a simple react application you can follow the steps mentioned below: 

Step 1: Create React application.

npx create-react-app foldername

Step 2: Move into the project folder.

cd foldername

 

Step 3: Create a components folder and now Project Structure will look like:

Project Structure

This was basically the initial setup we require for our application. Now let us take a look at each of the components individually. Custom components reside in the components folder, with everything put together in the MainComponent.jsx, we will place this component inside App.js, which itself goes under the “root” DOM node, and everything inside this node will be managed by React DOM.

We are going to develop three components:

  • Main Component: Responsible for fetch operation and state changes in the application.
  • Search Bar: A search bar to get the user input for the show name/keyword.
  • ShowInfoCard: A reusable component to display the show information.

Step 4: In the MainComponent.jsx component, we have a state variable, data which will hold the response for the GraphQL API. 

const [data, setData] = useState(Object);

To fetch the information, we make a call to the apiEndpoint, but first let us break the GraphQL query apart, in general, to form a query, you must specify fields within fields until those fields resolve to actual data. In this way, you ask for specific fields on objects and get back exactly what you asked for. The structure of any GraphQL query looks like this: 

query {
    JSON objects to retrieve
}

With our query variable, we are trying to fetch all the shows available, using name/keyword, which is passed as an argument with $term. 

MainComponent.jsx (query part)




const apiEndpoint = "https://tmdb.apps.quintero.io/";
const query = `
    query FetchData($term: String!){
        tv{
            search(term:$term){
              edges{
                node{
                    id
                    originalName
                }
              }
           }
        }
     }
`;


To make the request using Fetch API, we send the GraphQL query and variables as a JSON object to the endpoint. GraphQL endpoint expects the body of the request to be a stringified JSON object that contains query and variables parameters. When the request is complete, the promise is resolved with the response object. This object is basically a generic placeholder for various response formats. response.json()  is used to extract the JSON object from the response, it returns a promise, which is again resolved and data is updated.
MainComponent.jsx ( request part )

 

MainComponent.jsx (request part)




const getData = (term) => {
       fetch(apiEndpoint, {
           method: "POST",
           headers: { "Content-Type": "application/json" },
           body: JSON.stringify({
               query,
               variables: { term }
           })
       })
           .then(res => res.json())
           .then((data) => setData(data))
           .catch(console.error);
 };


So finally our MainComponent.jsx looks like:

MainComponent.jsx




import React, { useState } from "react";
import SearchBar from "./SearchBar";
import ShowInfoCard from "./ShowInfoCard";
  
function Main() {
    const [data, setData] = useState(Object);
    const apiEndpoint = "https://tmdb.apps.quintero.io/";
    const query = `
        query FetchData($term: String!){
            tv{
                search(term:$term){
                  edges{
                    node{
                        id
                        originalName
                    }
                  }
                }
              }
        }
    `;
  
    const getData = (term) => {
        fetch(apiEndpoint, {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
                query,
                variables: { term }
            })
        })
            .then(res => res.json())
            .then((data) => setData(data))
            .catch(console.error);
    };
    // console.log(data)
    return (
        <div>
            <SearchBar getData={getData} />
            {data.data ? data.data.tv.search.edges.map(({ node }) => (
                <ShowInfoCard key={node.id} node={node} />
            )) : <div></div>
            }
        </div>
    );
  
}
  
export default Main;


Step 5: Now, moving on to the SearchBar component, which serves the purpose of receiving the user input for name/keyword. It is a simple component, with an input field of text type, and a button to make the search request. The state variable term is updated holds the input from user, and is passed as an argument to getData() when the user makes the search request.

SearchBar.jsx




import React, { useState } from "react";
  
function SearchBar({getData}){
    const [term, setTerm] = useState("");
    const onChange = (e) =>{
        setTerm(e.target.value)
    }
    const onSearch = () =>{
        getData(term)
    }
    return(
        <div className="searchbar">
        <input 
            placeholder="Enter the name..."
            type="text" 
            value={term}
            onChange={(event) => {onChange(event)}}
            onKeyUp={(event) => {onChange(event)}}
            onPaste={(event) => {onChange(event)}}
        />
        <button type="button" className="searchButton" 
                onClick={onSearch}>Search
        </button>
        </div>
    );
}
  
export default SearchBar;


Step 6: Our last component, is a reusable UI component, which is basically a Card Component that receives node ( contains the show information ) as props, and just displays it in any chosen format. You can tweak the App.css file to understand the various design aspects. 

ShowInfoCard.jsx




import React from "react";
  
function ShowInfoCard({ node }) {
    return (
        <div className="datacontainer">
            <div className="dataitem">
              Name : {node.originalName}
            </div>
        </div>
    );
}
  
export default ShowInfoCard;


Step 7: Finally, we need to include the MainComponent in App.js file:

App.js




import './App.css';
import React from "react";
import Main from './components/MainComponent';
  
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h2>Consuming a GraphQL API</h2>
      </header>
      <Main />
    </div>
  );
}
  
export default App;


Step to run the application: To run the application on your system, run the following command:

npm start

Output:

GraphQL API: https://github.com/nerdsupremacist/tmdb

Fetch API: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API



Last Updated : 13 Dec, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads