mickhansen/graphql-sequelize

Question: Using dataloader-sequelize with multiple databases

rcpu opened this issue · 5 comments

rcpu commented

Hi,
I am having an application which is having multiple databases, with same schema structure. When a request arrives based on the user, we resolve it to the right database models dynamically.

Is there any examples on switching the data loader context dynamically.

Code Snippet;
Query Schema:
attendances: {
type: new graphql.GraphQLList(companyDB.StaffAttendance.GQLStaffAttendance),
args: defaultListArgs(companyDB.StaffAttendance),
resolve: resolver(
function (findOptions, args, context, info) {
let user = session.get('user');
#WOULD LIKE TO UPDATE THE DATALOADER CONTEXT HERE
return userDB(user, context).StaffAttendance;
}, {
before: (findOptions, args, context, info) => {
findOptions = resolveArgs(findOptions, args);
return findOptions;
}
})
},

#Default dataloaderContext
module.exports = expressGraphql({
schema: schema,
graphiql: false,
context(req) {
const dataloaderContext = dataloader.createContext(companyDB.sequelize);
resolver.contextToOptions = {
dataloaderContext: [EXPECTED_OPTIONS_KEY]
};
return {
...req,
dataloaderContext
};
},
formatError: formatError
});

So all context to options does is translate some context value to some options value.
You could do this yourself via before hooks

Here's a nasty hack to make it work for multiple databases for those interested:

const context1 = createContext(sequelize1);
const context2 = createContext(sequelize2);

return {
  ...context1,
  loaders: {
    ...context1.loaders,
    ...context2.loaders,
  },
};

However this method is brittle and may break with any upgrade to this library or dataloader-sequelize. Use at your own risk!

@scarlac that should work yeah, assuming no shared model names across the two databases. I guess to make it less brittle we could provide an official mergeContexts method for cases like these.

@mickhansen That would be great. Our situation is that we have 1 schema but several data sources so we'd have no conflicts. Should I make a PR?

stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.