Reputation: 13811
I'm having a dataloader along with my graphql like the following:
async function testDataLoader(accountNumber, req, args) {
const dummy = new DataLoader(async accountNumber => {
return new Promise(async (resolve, reject) => {
// rest call
return resolve([<rest result>])
});
});
return dummy.load(accountNumber)
}
export default {
Friends: {
query1: async ({req, args}) => {
const data = await testDataLoader(["12121"], req, args);
// do something with data
}
query2: async ({req, args}) => {
const data = await testDataLoader(["12121"], req, args);
// do something with data
}
}
};
When we query like:
Friends {
query1
query2
}
I expect dataloader to call my rest services only once. However, I could able to see my rest is called twice. Not sure, where I'm making the mistakes.
Upvotes: 0
Views: 1743
Reputation: 84687
The issue is that every time you're calling testDataLoader
, you're creating a new instance of DataLoader. You should create a single DataLoader instance per request (per resource you're loading). This way every time you call load
you're interacting with the same cache.
You could do something like:
const dummy = new DataLoader(...);
async function testDataLoader(accountNumber) {
return dummy.load(accountNumber)
}
But this would persist the DataLoader between requests, which you don't want to do. What you should do is create the DataLoader instance as part of your context, which is recreated each time a request is executed.
const context = async ({ req }) => {
return {
testLoader = new DataLoader(...),
};
},
const server = new ApolloServer({
...
context,
})
Then just call your loader directly inside your resolver:
query2: async (parent, args, context) => {
const data = await context.testLoader.load(["12121"]);
...
}
Upvotes: 3