Comprehensive Guide to GraphQL Clients, part 1
Tags: graphql, react, webdev, javascript
Published: 2022-04-09 10:16:19


## Introduction

As you already know, GraphQL is a query language for APIs. It is a declarative language, which means that it is easy to write queries. However, it is also a flexible language, which means that it is easy to write queries that are not declarative. This guide will help you to write declarative queries. Until now, you have created a server that returns data. However, you have not used the data in any way. This guide will help you to use the data in a declarative way.
GraphQL clients are used to sending queries to a GraphQL server. Requests are sent in the form of a query string. The response is returned in the form of a JSON object. The response is a JSON object that contains the data that is requested. A request is made to a GraphQL server using the HTTP protocol, so you can use the same client as a client for RESTful APIs.

## Getting Started

## GraphQL IDE's

IDEs are test tools to check the correctness of your queries. You can define your queries in the IDE and then send them to the server. The server will return the data that is requested if the query is correct. There are a lot of IDEs available.
The most popular and the simplest IDE for GraphQL queries is [GraphiQL](https://github.com/graphql/graphiql).
The modern clone of GraphiQL is [GraphQL Playground](https://www.electronjs.org/apps/graphql-playground). The environment is cleaner and has some advanced features.
The recent IDE for GraphQL queries is [Apollo Explorer](https://studio.apollographql.com/).
All-around tools such as [Postman](https://www.getpostman.com/) and [Insomnia](https://www.insomnia.rest/) are great tools for testing either GraphQL queries or RESTful APIs.

## Curl

The tool for quickly sending queries to a GraphQL server is [curl](https://curl.haxx.se/). It is a command-line tool that allows you to send simple queries to a GraphQL server.

```
curl  -X POST -H "Content-Type: application/json" -d '{"query": "{countries { name }}"}' 'https://countries.trevorblades.com/'
```

It is useful for debugging and quick testing.

## Install ReactJS

The first step is to install ReactJS as our library of choice for creating UI components.
If you have not installed ReactJS, you can install it using the following command in the command line:

```
npx create-react-app my-app
cd my-app
npm start
```

Now you are ready to deep dive into the GraphQL world.

## Native Fetch

Fetch is a native built-in JavaScript client for making HTTP requests. Let's see how to use fetch to send a query to a GraphQL server.

Create a file FetchData.js in the root of your project.

```
import { useState, useEffect } from "react";

const FetchedData = () => {
  const [country, setCountry] = useState();
  const fetchData = async (req, res) => {
    try {
      const response = await fetch("https://countries.trevorblades.com/", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          query: "{countries { name }}",
        }),
      });
      const { data } = await response.json();

      const countriesName = [];
      data.countries.map((c) => countriesName.push(c.name));
      setCountry(countriesName);
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    fetchData();
  }, []);
  const countriesList = country?.map((c, index) => <ul key={index}>{c}</ul>);
  return (
    <>
      <h1>Countries</h1>
      {countriesList}
    </>
  );
};

export default FetchedData;
```

Then in App.js, you can use the component FetchedData.

```
import FetchedData from "./FetchData";

export default function App() {
return <FetchedData />;
}
```

## Axios

Axios is a JavaScript library for making HTTP requests. It is a wrapper around the XMLHttpRequest object. It's a promise-based HTTP client for the browser and node.js.
Axios automatically parses JSON responses. It is a shorthand for fetch.
Install Axios using the following command in the command line:

```
npm install axios
``` 

- FetchData.js

```
import { useState, useEffect } from "react";
import axios from "axios";

const FetchedData = () => {
  const [country, setCountry] = useState();
  const fetchData = async (req, res) => {
    try {
      const response = await axios.post("https://countries.trevorblades.com/", {
        query: " {countries { name }}"
      });

      const { data } = response.data;

      const countriesName = [];
      data.countries.map((c) => countriesName.push(c.name));
      setCountry(countriesName);
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    fetchData();
  }, []);
  const countriesList = country?.map((c, index) => <ul key={index}>{c}</ul>);
  return (
    <>
      <h1>Countries</h1>
      {countriesList}
    </>
  );
};

export default FetchedData;
```

App.js is the same as before.

## graphql-request

For simple requests, graphql-request is a good choice. This library is only '5.2kb' and it is one of the fastest and lightest GraphQL clients. It supports async/await, typescript, isomorphism, and works on both the client and server sides.

Install graphql-request:

```
npm install graphql-request graphql
```

Then, you need to import the library and create a client.
If you are not familiar with the code in these examples, I recommend you to read the documentation about the fundamentals of React.

- FetchData.js

```
import { useState, useEffect, useCallback } from "react";
import { request, gql } from "graphql-request";

const FetchedData = () => {
  const [country, setCountry] = useState();

  const countriesQuery = gql`
    query {
      countries {
        name
      }
    }
  `;

  const url = "https://countries.trevorblades.com/";

  const fetchData = useCallback(async () => {
    try {
      const response = await request(url, countriesQuery);

      const { countries } = response;

      const countryName = countries?.map((c, i) => <ul key={i}>{c.name}</ul>);
      setCountry(countryName);
    } catch (error) {
      console.log(error);
    }
  }, [countriesQuery]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  return (
    <>
      <h1>Countries</h1>
      {country}
    </>
  );
};

export default FetchedData;
```

App.js is the same as in the previous example.

## graphql-hooks

Graphql-hooks is a library that allows you to use GraphQL clients in React. It is a promise-based library for the browser and node.js. Conceptually, it is similar to graphql-request, but the difference is that first is formed a client and then the whole app is wrapped in a context in which the client is available(wrapping app). Tiny bundle: only 7.6kB (2.8 gzipped)

Install graphql-hooks:

```
npm install graphql-hooks
```

- App.js

```
import FetchedData from "./FetchData";
import { GraphQLClient, ClientContext } from "graphql-hooks";

const client = new GraphQLClient({
  url: "https://countries.trevorblades.com/"
});

export default function App() {
  return (
      <ClientContext.Provider value={client}>
        <FetchedData />
      </ClientContext.Provider>
  );
}
```

- FetchData.js

```
import { useState, useEffect, useCallback } from "react";
import { useQuery } from "graphql-hooks";

const FetchedData = () => {
  const [country, setCountry] = useState();

  const countriesQuery = `
    query {
      countries {
        name
      }
    }
  `;

  const { loading, error, data } = useQuery(countriesQuery);

  const fetchData = useCallback(async () => {
    try {

      const { countries } = data;
      console.log(countries);


      const countryName = countries?.map((c, i) => <ul key={i}>{c.name}</ul>)
      setCountry(countryName);
    } catch (error) {
      console.log(error);
    }
  }, [data]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <>
      <h1>Countries</h1>
      {country}
    </>
  );
};

export default FetchedData;

```

If you don't need advanced features, graphql-hooks is an ideal choice, because it is very functional and easy to use. It is also very lightweight. Even has a self-contained development environment in form of extension.