How to use Mongoose with GraphQL and DataLoader? How to use Mongoose with GraphQL and DataLoader? mongoose mongoose

How to use Mongoose with GraphQL and DataLoader?


Keep your mongoose schema in a separate module. You don't want to create your schema each request -- just the first time the module is imported.

const userSchema = new Schema({  name: String,  friendIds: [String]})const User = mongoose.model("User", userSchema)module.exports = { User }

If you want, you can also export a function that creates your loader in the same module. Note, however, that we do not want to export an instance of a loader, just a function that will return one.

// ...const getUserLoader = () => new DataLoader((userIds) => {  return User.find({ _id: { $in: userIds } }).execute()})module.exports = { User, getUserLoader }

Next, we want to include our loader in the context. How exactly this is done will depend on what library you're using to actually expose your graphql endpoint. In apollo-server, for example, context is passed in as part of your configuration.

new ApolloServer({    typeDefs,    resolvers,    context: ({ req }) => ({        userLoader: getUserLoader()    }),})

This will ensure that we have a fresh instance of the loader created for each request. Now, your resolvers can just call the loader like this:

const resolvers = {  Query: {    users: async (root, args, { userLoader }) => {      // Our loader can't get all users, so let's use the model directly here      const allUsers = await User.find({})      // then tell the loader about the users we found      for (const user of allUsers) {        userLoader.prime(user.id, user);      }      // and finally return the result      return allUsers    }  },  User: {    friends: async (user, args, { userLoader }) => {      return userLoader.loadMany(user.friendIds)    },  },}