နားလည်ထားရမယ့် အချက်
Tutorials list N ခု query ဖြစ်ပြီး tutorial တစ်ခုချင်းစီရဲ့ `author` field ကို resolver က database query တစ်ခုချင်းစီ သီးခြားခေါ်ရင် list query 1 ခု + author query N ခု = N+1 queries ဖြစ်သွားပါတယ်—result count များလာလေ database load ကြီးလေဖြစ်ပါတယ်။ DataLoader က request တစ်ခုအတွင်း field resolver calls များကို event loop tick တစ်ခုအတွင်း batch လုပ်ပြီး unique key များအတွက် database call တစ်ခါတည်း (`WHERE id IN (...)`) ခေါ်ကာ result များကို in-request cache ထဲထားပေးပါတယ်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Tutorial Platform homepage က tutorial 20 ခု list ကို author name ပါအောင် ပြသရာမှာ naive resolver က author query 20 ခု ခွဲခေါ်ခဲ့ပေမယ့် `authorLoader` ကို context ထဲထည့်ပြီးသုံးလိုက်ရင် author query တစ်ခုတည်းသာ ဖြစ်သွားပါတယ်။ Loader instance ကို request တစ်ခုချင်းစီအတွက် အသစ်ဖန်တီးရမယ်—loaders ကို request အချင်းချင်းကြား share မလုပ်ရပါ (stale/leaked cache ရှောင်ဖို့)။
အတူတူ စမ်းရေးကြည့်မယ်
const authorLoader = new DataLoader(async (authorIds) => {
const authors = await db.author.findMany({
where: { id: { in: authorIds } },
});
const byId = new Map(authors.map((author) => [author.id, author]));
return authorIds.map((id) => byId.get(id) ?? null);
});
const resolvers = {
Tutorial: {
author: (tutorial, _args, context) =>
context.loaders.author.load(tutorial.authorId),
},
};N+1 problem ကို ဖော်ထုတ်ပြီး DataLoader ဖြင့် batching resolver ကို ရေးနိုင်မည်။၅ မိနစ် စမ်းကြည့်
`Tutorial.comments` field အတွက် `commentsByTutorialLoader` တစ်ခု design လုပ်ပြီး batch function ရဲ့ return order requirement (input keys order နဲ့ ကိုက်ရမည်) ကို ရေးပါ။
သတိလေးတစ်ချက်
DataLoader batch function ကနေ result array ကို input keys order နဲ့ မကိုက်အောင် ပြန်ပေးမိရင် wrong author ကို wrong tutorial နဲ့ တွဲသွားနိုင်ပါတယ်—`keys.map(...)` pattern ဖြင့် order အမြဲထိန်းပါ။
Apollo Server — Batching with DataLoader — GraphQL