Apollo Server 4 and apollo-datasource-mongodb

Hi, I’m trying to get a simple example running with V4 Server and mongo datasource.
Getting: “Context creation failed: MongoDataSource constructor must be given a collection or Mongoose model”

I’m a newbe, anyone get this going? Any help / guidance would be appreciated.
Thanks,
Roy

Hey @Royt, data sources changed a bit in v4 so you might be working with some older documentation (the apollo-datasource-mongodb has not been updated/published since v4 so it’s dated).

Our migration guide explains how to use data sources that were compatible with v3 in v4.

Thanks Trevor, 5 minutes after I posted, I got it running!
This seems to work, saves and queries a simple employee doc {first Name, LastName} using mongodb data source package. Can you review and let me know if I did anything egregious?

Thanks,
Roy

const { ApolloServer } = require(“@apollo/server”);
const { startStandaloneServer } = require(‘@apollo/server/standalone’);
const { MongoDataSource } = require(“apollo-datasource-mongodb”);
const mongoose = require(“mongoose”);

const typeDefs = #graphql type Employee { firstName: String lastName: String } type Query { employees: [Employee] } type Mutation { CreateEmployee(firstName: String!, lastName: String!): Employee } ;

const EmployeeModel = mongoose.model(“Employee”, {
firstName: String,
lastName: String,
});
const resolvers = {
Query: {
employees: (, __, contextValue) => {
return contextValue.dataSources.employees.getEmployees()
},
},
Mutation: {
CreateEmployee: (
, args, contextValue) => {
return contextValue.dataSources.employees.createEmployee(args)
},
},
};

class Employees extends MongoDataSource {
constructor(options) {
super(options);
this.initialize({ cache: options.cache, context: options.token });
}
async getEmployees() {
return await this.model.find();
}
async createEmployee(args) {
return await this.model.create(args);
}
}

const server = new ApolloServer({
typeDefs,
resolvers,
});
const MONGODB_URL = “mongodb://127.0.0.1:27017/test”;
async function connectMongodb() {
await mongoose.connect(MONGODB_URL);
console.log(“Connected to database successfully :tada:”);
}
(async () => {
// Connect to DB
try {
await connectMongodb();
} catch (e) {
console.error(e);
throw new Error(Unable to connect to database);
}

const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
context: async ({req}) => {
const { cache } =server;
const token = req.headers.token;
return {
dataSources: {
employees: new Employees(EmployeeModel),
},
token,
};
},
});
console.log(🚀 Server ready at ${url});
})();

Seems reasonable at a glance, though that code is really tough to read and I can’t format it in my editor without changing a bunch of characters / fixing up the paste job.

In the future, put your code between triple backticks for better formatting (```) so all of your other stuff isn’t formatted by markdown (like underscores etc.)

Hello, I am using mongoose, but I’d like to use the added functionality of datasources, is there a way to implement that using apollo server V4?

—Edit—
Figured it out after trials and errors.

Use datasources with mongoDb (mongoose) the recommended way by following the steps in the docs. Here is how I implemented mine:
My datasource:


import User from "../models/user.js";

class MongoDatasource {
  constructor(dbConnection) {
    this.dbConnection = dbConnection;
  }
  async getUser() {
    return User.find();
  }
 
  }
}
export default MongoDatasource;


My resolver:

const resolvers = {
  Query: {
    user: (_, __, { dataSources }) => {
      return dataSources.mongoDataSource.getUser();
    },

  },

My database connection

const uri = process.env.MONGODB_URI;
const dbConnection = async () => {
  await mongoose.connect(uri, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  });
};

dbConnection()
  .then(console.log("🎉 connected to database successfully"))
  .catch((error) => console. Error(error));

My contex

context: async () => {
    
    

      return {
        const { cache } = server;
       
        dataSources: {
          mongoDataSource: new MongoDatasource({ cache }),

      
        },

Use the docs to set up your server and customize according to what your application need