As a part of JavaScript Marathon week, Star Richardson, Software Engineer at This Dot Labs, presented a session on GraphQL DataLoaders. She discussed the following topics:
What are GraphQL DataLoaders?
A dataloader is a generic utility used as part of your application's data fetching layer to provide a simplified and consistent API over various remote data sources, such as databases or web services, via batching and caching.
In sum, it is a very small library that provides batching and caching around your APIs.
DataLoaders can be used on any JavaScript project.
Why use DataLoaders?
DataLoaders can be used on any JavaScript project, but they work especially well with GraphQL because GraphQL has an “N + 1” problem, and DataLoaders are here to solve it!
What is N + 1 problem?
The problem is that in practice, you wouldn't just have one join. Your review data model might include associations with any number of other models, each one requiring its own join clause. Additionally, those models might have relationships to other models themselves. Trying to craft a single SQL query that will account for all possible GraphQL queries becomes not only difficult but also prohibitively expensive. A client might request only the reviews with none of their associated models, but the query to fetch those reviews now include 30 additional, unnecessary views. That query might have taken less than a second, but now takes 10.
You can read more about this problem here.
Let’s start with
First, install DataLoaders:
npm install --save dataloader
Second, Create DataLoader instance.
Finally, create a batching function.
Create your first DataLoader
First, create a new file and import the DataLoader library.
const DataLoader = require(‘dataloader’);
Then, import the model you want. For example:
const { Characters } = require(‘../../models’)
Next, create the DataLoader instance for this model.
const characterLoader = new DataLoader(getBatchCharacters);
You may be wondering: what is the getBatchCharacters
? Well it’s the batching function that we discussed before. Let’s create it!
Batching Functions
Batching functions for GraphQL Dataloaders need to follow the next specific structure in order to work with DataLoaders!
DataLoaders expect your batching function to accept an array of keys and return a promise that resolves to an array of values or errors. It’s very important that the array or the promise that it resolves to an array that you're returning is the same length and in the same order of the keys that you are receiving.
So our batching function will be for example like this:
const getBatchCharacters = async (keys) => {
const characters = await Character.findAll({
// Add your query here
});
};
And then export the dataloader:
module.exports = characterLoader;
If you missed the JavaScript marathon session on DataLoaders, you can check out the video here!