<olclass="chapter"><liclass="affix"><ahref="../index.html">Introduction</a></li><liclass="affix"><ahref="../quickstart.html">Quickstart</a></li><liclass="affix"><ahref="../types/index.html">Type System</a></li><li><ahref="../types/objects/defining_objects.html"><strongaria-hidden="true">1.</strong> Defining objects</a></li><li><olclass="section"><li><ahref="../types/objects/complex_fields.html"><strongaria-hidden="true">1.1.</strong> Complex fields</a></li><li><ahref="../types/objects/using_contexts.html"><strongaria-hidden="true">1.2.</strong> Using contexts</a></li><li><ahref="../types/objects/error_handling.html"><strongaria-hidden="true">1.3.</strong> Error handling</a></li></ol></li><li><ahref="../types/other-index.html"><strongaria-hidden="true">2.</strong> Other types</a></li><li><olclass="section"><li><ahref="../types/enums.html"><strongaria-hidden="true">2.1.</strong> Enums</a></li><li><ahref="../types/interfaces.html"><strongaria-hidden="true">2.2.</strong> Interfaces</a></li><li><ahref="../types/input_objects.html"><strongaria-hidden="true">2.3.</strong> Input objects</a></li><li><ahref="../types/scalars.html"><strongaria-hidden="true">2.4.</strong> Scalars</a></li><li><ahref="../types/unions.html"><strongaria-hidden="true">2.5.</strong> Unions</a></li></ol></li><li><ahref="../schema/schemas_and_mutations.html"><strongaria-hidden="true">3.</strong> Schemas and mutations</a></li><li><ahref="../servers/index.html"><strongaria-hidden="true">4.</strong> Adding A Server</a></li><li><olclass="section"><li><ahref="../servers/official.html"><strongaria-hidden="true">4.1.</strong> Official Server Integrations</a></li><li><olclass="section"><li><ahref="../servers/warp.html"><strongaria-hidden="true">4.1.1.</strong> Warp</a></li><li><ahref="../servers/rocket.html"><strongaria-hidden="true">4.1.2.</strong> Rocket</a></li><li><ahref="../servers/iron.html"><strongaria-hidden="true">4.1.3.</strong> Iron</a></li><li><ahref="../servers/hyper.html"><strongaria-hidden="true">4.1.4.</strong> Hyper</a></li></ol></li><li><ahref="../servers/third-party.html"><strongaria-hidden="true">4.2.</strong> Third Party Integrations</a></li></ol></li><li><ahref="../advanced/index.html"><strongaria-hidden="true">5.</strong> Advanced Topics</a></li><li><olclass="section"><li><ahref="../advanced/introspection.html"><strongaria-hidden="true">5.1.</strong> Introspection</a></li><li><ahref="../advanced/non_struct_objects.html"><strongaria-hidden="true">5.2.</strong> Non-struct objects</a></li><li><ahref="../advanced/implicit_and_explicit_null.html"><strongaria-hidden="true">5.3.</strong> Implicit and explicit null</a></li><li><ahref="../advanced/objects_and_generics.html"><strongaria-hidden="true">5.4.</strong> Objects and generics</a></li><li><ahref="../advanced/multiple_ops_per_request.html"><strongaria-hidden="true">5.5.</strong> Multiple operations per request</a></li><li><ahref="../advanced/dataloaders.html"class="active"><strongaria-hidden="true">5.6.</strong> Dataloaders</a></li><li><ahref="../advanced/subscriptions.html"><strongaria-hidden="true">5.7.</strong> Subscriptions</a></li></ol></li></ol>
<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="../print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"name="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<aclass="header"href="#avoiding-the-n1-problem-with-dataloaders"id="avoiding-the-n1-problem-with-dataloaders"><h1>Avoiding the N+1 Problem With Dataloaders</h1></a>
This can be done with Juniper using the crate <ahref="https://github.com/cksac/dataloader-rs">cksac/dataloader-rs</a>, which has two types of dataloaders; cached and non-cached.</p>
<p>DataLoader provides a memoization cache, after .load() is called once with a given key, the resulting value is cached to eliminate redundant loads.</p>
<p>DataLoader caching does not replace Redis, Memcache, or any other shared application-level cache. DataLoader is first and foremost a data loading mechanism, and its cache only serves the purpose of not repeatedly loading the same data in the context of a single request to your Application. <ahref="https://github.com/graphql/dataloader#caching">(read more)</a></p>
<p>Once created, a dataloader has the async functions <code>.load()</code> and <code>.load_many()</code>.
In the above example <code>cult_loader.load(id: i32).await</code> returns <code>Cult</code>. If we had used <code>cult_loader.load_many(Vec<i32>).await</code> it would have returned <code>Vec<Cult></code>.</p>
<p><strong>Dataloaders</strong> should be created per-request to avoid risk of bugs where one user is able to load cached/batched data from another user/ outside of its authenticated scope.
Creating dataloaders within individual resolvers will prevent batching from occurring and will nullify the benefits of the dataloader.</p>
<p>For a full example using Dataloaders and Context check out <ahref="https://github.com/jayy-lmao/rust-graphql-docker">jayy-lmao/rust-graphql-docker</a>.</p>