Introduction
GraphQL is a powerful tool for querying data from remote servers and my preferred way of building APIs (Application Programming Interface). For some people, it might be difficult to learn as the tutorials are usually written using tools such as Apollo or Relay. These tools are great but often suited for more complicated projects. In certain scenarios, there might be better to choose a more lightweight approach and not increase bundle size with additional libraries. In these cases, you can work directly with the tools available in the browser. In this quick tutorial, we will use fetch, commonly available in your browser. Let’s first quickly revise what fetch is and how it is usually used with REST API, then we can move to simple GraphQL queries execution.
Using Fetch for a simple GET request
Fetch is a modern replacement for older XMLHttpRequest, a tool for sending network requests. It solves a number of problems for fetching data from servers, such as promise chaining. While we will not go into the detail of older XMLHttpRequest in this article, it is important that for historical reasons, you need to count that fetch is not supported in older browsers. If you need to include for example also IE11, you would need to use a polyfill. Check the caniuse page for browser support. In terms of fetch usage outside of the browser, you can use it natively from Node.js 17 as an experimental feature, in earlier versions you can install for example node-fetch library.
The following is an example of a simple request for fetching data allowing you to receive the current Bitcoin price in USD from Yahoo Finance API.
const url = 'https://query1.finance.yahoo.com/v8/finance/chart/BTC-USD';
const options = {
method: 'GET',
};
fetch(
url,
options
)
.then((response) => {
return response.json();
})
.then((data) => {
const res = data.chart.result;
console.info(res);
return res;
})
.catch((err) => {
console.log('err', err)
});
We can see that there are two parameters passed into the fetch function, the URL of the API endpoint and the options parameter, which is for additional configuration, such as the method of the request, headers, Cross-Origin Resource Sharing (CORS) configurations, as well as body for the POST request. The subsequent .then() calls allow us to chain asynchronous promises. In other words, it says that you are first waiting for the result from the API. If it is successful, then we will get the response and convert it using the .json() method. After that, we will wait again on the result of the conversion, where we can finally log the data into the console. For my execution the shortened result is as follows:
{
"data": {
"allFilms": {
"films": [
{
"title": "A New Hope",
"releaseDate": "1977-05-25"
},
{
"title": "The Empire Strikes Back",
"releaseDate": "1980-05-17"
}
]
}
}
}
You can notice that .catch() method has not been triggered. If everything works properly, only success callbacks are executed, however, if we encounter an error during the request, the error callback will get triggered.
Using Fetch for GraphQL Query
In the previous example, we used the public REST API from Yahoo Finance to execute GET requests for data retrieval. In the second example, we need a GraphQL endpoint for Star Wars API. GraphQL offers the so-called introspection of the schema, which allows us to easily document what data we can retrieve from the server as you can see on the documentation link.
In order to execute the GraphQL query, we need to use the POST method, set content as application/json, and also send GraphQL document stringified in the JSON body. Now, let's move to our example. The GraphQL document attached to the request will look as follows:
query ($first: Int) {
allFilms(first: $first) {
films {
title
releaseDate
}
}
}
Querying is similar to GET requests in REST API and only retrieves data. With GraphQL we need to describe exactly the data that we would like to retrieve. You can see that we have specified to retrieve films with titles and release dates. $first is the so-called variable, this is needed to pass dynamic data to the query and allows us to take just the first n films from the query.
Let’s now move to the exact JavaScript code:
const url = 'https://swapi-graphql.netlify.app/.netlify/functions/index';
const GET_FILMS = `query ($first: Int) {
allFilms(first: $first) {
films {
title
releaseDate
}
}
}`;
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: GET_FILMS,
variables: {
first: 2
}
})
};
const fetchAPI = async () => {
try {
const result = await fetch(
url,
options
);
const data = await result.json();
console.info(data);
} catch (err) {
console.info(err)
}
}
await fetchAPI();
We have defined the URL for GraphQL API and our GraphQL document. In this case, we need to specify options as a second argument. As noted above, the option method needs to be set to POST and content should be set to application/json. The body should be stringified JSON with two keys:
- query - where we will pass the GraphQL document
- variables - which should match the variable definition in the document and schema on the server
You can also note that in the first example with GET request, we have used .thenable() promise chaining, but here we have used async await. Now, when we execute the result, we will obtain the following result:
{
"data": {
"allFilms": {
"films": [
{
"title": "A New Hope",
"releaseDate": "1977-05-25"
},
{
"title": "The Empire Strikes Back",
"releaseDate": "1980-05-17"
}
]
}
}
}
Summary
This is a brief introduction to fetch usage for GraphQL queries, the principle for the mutation will be practically the same as for queries, i.e. passing query and variables. While on complex projects you should strive to use a GraphQL client, such as Apollo, Relay, or others, fetch has an important role, when you need to keep the project size at a minimum. Axios is also a good alternative way to fetch. Be sure to consider browser support when using the fetch. If you like to learn more about GraphQL, e.g. going through the exact structure of the document, queries, mutations, and best practices, be sure to check my free course on GraphQL language.
Top comments (2)
🚀
thanks Jan!