mickhansen / graphql-sequelize

GraphQL & Relay for MySQL & Postgres via Sequelize
MIT License
1.9k stars 172 forks source link

Question: Using dataloader-sequelize with multiple databases #683

Closed rcpu closed 4 years ago

rcpu commented 4 years ago

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 });

mickhansen commented 4 years ago

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

scarlac commented 4 years ago

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!

mickhansen commented 4 years ago

@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.

scarlac commented 4 years ago

@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[bot] commented 4 years ago

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.