DataLoader je super nástroj pro optimalizaci dotazů v GraphQL. Pomáhá eliminovat N+1 problém, kdy se při dotazování na vztahové entity provádí spousta zbytečných dotazů na databázi. Je to takový caching mechanismus, který shromažďuje dotazy a provádí je najednou, což výrazně zrychluje načítání dat.
Implementace DataLoaderu je docela jednoduchá. Vytvoříš si instanci DataLoaderu v resolveru a pak ji použiješ k načítání dat. Například, když máš typ User
, který má vztah posts
, tak místo toho, abys pro každý uživatelský dotaz spouštěl samostatný dotaz na příspěvky, tak to uděláš jedním hromadným dotazem. Tady je jednoduchý příklad:
const DataLoader = require('dataloader');
const postLoader = new DataLoader(async (userIds) =\> \{
const posts = await getPostsByUserIds(userIds);
return userIds.map(id =\> posts.filter(post =\> post.userId === id));
\});
const resolvers = \{
User: \{
posts: (user) =\> postLoader.load(user.id),
\},
\};
Nejlepší praxí je mít DataLoader jako singleton nebo ho vytvářet na úrovni kontextu GraphQL serveru, aby se sdílel napříč různými resolvery během jednoho požadavku. Takže ho nespouštěj pro každý jednotlivý resolver.
Co se týče situací, kdy se DataLoader nehodí, tak pokud máš například velmi malé množství dat, kde by nebylo ani potřeba batching nebo caching, tak by to mohlo být zbytečné. Nebo když data často měníš a potřebuješ vždy čerstvá data přímo z DB.
Celkově ale doporučuji ho použít tam, kde máš víc jak pár dotazů na databázi a chceš ušetřit čas a zdroje.