From 2df5ecae79bc109a2a7502eef07633be48a1827e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Georget?= Date: Sat, 5 Jan 2019 18:14:00 +0100 Subject: [PATCH] Reset loaders on every request to avoid wrong results coming from cache --- .../strapi-plugin-graphql/services/Loaders.js | 22 +++++++++++++++++-- .../strapi-plugin-graphql/services/Query.js | 5 +++++ .../services/Resolvers.js | 3 --- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/strapi-plugin-graphql/services/Loaders.js b/packages/strapi-plugin-graphql/services/Loaders.js index 1c59ed1811..63a3b2f16f 100644 --- a/packages/strapi-plugin-graphql/services/Loaders.js +++ b/packages/strapi-plugin-graphql/services/Loaders.js @@ -12,8 +12,26 @@ const DataLoader = require('dataloader'); module.exports = { loaders: {}, - createLoader: function(model) { - this.loaders[model] = new DataLoader(keys => { + initializeLoader: function() { + // Create loaders for each relational field (exclude core models). + Object.keys(strapi.models) + .filter(model => model !== 'core_store') + .forEach(model => { + (strapi.models[model].associations || []).forEach(association => this.createLoader(association.collection || association.model, association.plugin)); + }); + + // Reproduce the same pattern for each plugin. + Object.keys(strapi.plugins).forEach(plugin => { + Object.keys(strapi.plugins[plugin].models).forEach(model => { + (strapi.plugins[plugin].models[model].associations || []).forEach(association => this.createLoader(association.collection || association.model, association.plugin)); + }); + }); + }, + + createLoader: function(model, plugin) { + const name = plugin ? `${plugin}__${model}`: model; + + this.loaders[name] = new DataLoader(keys => { return new Promise(async (resolve, reject) => { try { // Extract queries from keys and merge similar queries. diff --git a/packages/strapi-plugin-graphql/services/Query.js b/packages/strapi-plugin-graphql/services/Query.js index f4801c243a..e096881f26 100644 --- a/packages/strapi-plugin-graphql/services/Query.js +++ b/packages/strapi-plugin-graphql/services/Query.js @@ -10,6 +10,8 @@ const _ = require('lodash'); const pluralize = require('pluralize'); const policyUtils = require('strapi-utils').policy; +const Loaders = require('./Loaders'); + module.exports = { /** * Convert parameters to valid filters parameters. @@ -256,6 +258,9 @@ module.exports = { return policy; } + // Initiliase loaders for this request. + Loaders.initializeLoader(); + // Resolver can be a function. Be also a native resolver or a controller's action. if (_.isFunction(resolver)) { context.query = this.convertToParams(options); diff --git a/packages/strapi-plugin-graphql/services/Resolvers.js b/packages/strapi-plugin-graphql/services/Resolvers.js index cd2800e4f3..849b7b9c80 100644 --- a/packages/strapi-plugin-graphql/services/Resolvers.js +++ b/packages/strapi-plugin-graphql/services/Resolvers.js @@ -362,9 +362,6 @@ module.exports = { default: } - // Create dynamic dataloader for query batching and caching. - Loaders.createLoader(association.collection || association.model, association.plugin); - _.merge(acc.resolver[globalId], { [association.alias]: async (obj, options) => { // eslint-disable-line no-unused-vars