reactioncommerce / reaction-feature-requests

Reaction Feature Requests
13 stars 1 forks source link

Introduce DataLoaders into the GraphQL layer to reduce number of DB calls #70

Closed alex-haproff closed 5 years ago

alex-haproff commented 5 years ago

DataLoaders (https://github.com/graphql/dataloader) are useful in solving the n+1 problem so often encountered whilst building GraphQL APIs. DataLoaders act as a query batching and caching solution. A good example to start with is imports/plugins/core/core/server/no-meteor/queries.js. There we have shopById query used in a resolver for a product variant. shopById issues a query to Mongo context.collections.Shops.findOne({ _id }). On a product listing page shopById gets called with the same shopId for every product and product variant, which results in a significant number of queries to Mongo which can be avoided. The lookup itself is fast as this collection is indexed. However we still have an unnecessary number of roundtrips to the DB. Another example isimports/plugins/included/simple-inventory/server/no-meteor/utils/inventoryForProductConfigurations.js. The call to fetch inventory information SimpleInventory.find(...) would benefit from batching if there was a DataLoader in place.

A proposed architecture would allow each plugin to register their own DataLoaders map using functionsByType prop in the plugin's register.js. Each plugin would then provide a factory function to create DataLoaders, which will then be merged into context.dataLoaders and re-created on every request, as suggested here (https://github.com/graphql/dataloader#caching-per-request).