Prevent duplicate REST requests
Several GraphQL fields need the same remote resource during one operation.
GraphQL · Const
DataLoader batches keyed data fetches and memoizes repeated keys, helping GraphQL resolvers avoid duplicate backend requests. Create it with a function that maps a list of keys to the corresponding objects.
DataLoader is a utility for a data-fetching layer that accepts keys, resolves them in batches, and caches repeated lookups. In GraphQL resolvers, load() and loadMany() help avoid repeated backend requests for the same data.
new DataLoader(keys => Promise.all(keys.map(fetchFunction)))| Name | Type | Description |
|---|---|---|
keys | list of keys | Keys collected for the batch operation; the example uses REST API URLs. |
The batch function returns the objects corresponding to the supplied keys; individual load calls return the associated value or Promise.
import DataLoader from "dataloader";
const personLoader = new DataLoader(async (urls: readonly string[]) =>
Promise.all(urls.map(fetchPersonByURL))
);
async function fetchPersonByURL(url: string) {
const response = await fetch(url);
return response.json();
}
const person = await personLoader.load("https://example.com/person/1");The loader receives keys, fetches the corresponding people together, and memoizes repeated keys during its lifetime.
Several GraphQL fields need the same remote resource during one operation.
Many resolver calls request related records from a backend.
A resolver needs one or several resources through a shared loader.
DataLoader accepts a batch function that resolves a list of objects from a list of keys. It combines requested keys and can memoize results, reducing duplicate backend requests.
Follow-up: What does the batch function receive? It receives the keys collected by the loader, such as URLs, and returns the corresponding results in the batch.
Use load() for one key and loadMany() for multiple keys. Both allow callers to request data without repeatedly contacting the backend for the same key.
Follow-up: When is memoization useful? It is useful when multiple resolvers request the same resource during the loader's lifetime.
The constructor receives a function that maps a list of keys to a list of results. For URL-backed data, that function can fetch each URL and combine the resulting promises.
Follow-up: What runtime features does the implementation rely on? It relies on Promise and Map, supplied natively or by polyfills.
load()loadMany()PromiseMapGraphQL schemaresolver