Recommendations for MongoDB Driver and Schema solutions?

I"m looking to use it with MongoDB too. Just started today. Did you make any progress on this? I’d love to know how you configured it to work directly with MongoDB.

I will say that one of the issues I’d imagine that’s a huge impediment to what you are trying to do is that the API is setup to use GraphQL as it’s interface to the DB I think and that’s not necessary with MongoDB. I think you’d have to throw out the whole pre-configured API portion of the project, install mongoosejs as you suggested in Option 1 and then connect to MongoDB from there.

Not sure if this would create a bigger mess than either of us would want to take on, but it’s been something I thought was odd from the beginning that they don’t just use the CLI to ask which DB you want. Maybe it’s too much to ask at this stage, but regardless it’s what I’d hoped for.

Hi @misterhtmlcss welcome to the Redwood community! I’m on the Redwood Core Team — happy to help you find your way around and get settled in beyond any DB questions as well. Reach out anytime.

the API is setup to use GraphQL as it’s interface to the DB

^^ this is (thankfully) not correct. For reference, here’s a diagram of Redwoods Architecture. Even though Redwood’s API is a GraphQL endpoint, it’s connecting directly to the DB (by default using Prisma). Swap out prisma with mongoosejs in the diagram and you’re off to the races.

Given that there’s a lot of additional goodness that comes with Redwood’s API structure, I’m just not sure Mongoose is even needed — it’s probably overkill. Thus my curiosity about using the MongoDB NodeJS driver.

Make sense?

1 Like

Having fiddled around myself with connecting Redwood to a database that veers off the happy path I think until you try to build a simple app with both approaches you’ll have a hard time predicting ahead of time what the pros and cons are of different approaches.

I don’t have much experience with Mongoose but the question I would ask is how many things in the core tutorial would you be able to do with just the Node driver versus bringing in something like Mongoose? If the Node driver can get through the same flow without too many extra steps than Mongoose would probably be overkill.

2 Likes

Thank you for the warm welcome. I’ll definitely reach out.

Also I’ll definitely try it. I’m going to spin up a small little todo app using RedwoodJS and Mongoose/mongoDB.

@ajcwebdev you make a great point. I think you always need to consider which tool is best. For me and my typical stack I find Mongoose is usually the best choice so I usually practice everything with it, just so I’m always becoming better with the tool. And yes a todo app doesn’t need Mongoose, but the next app might and I’d like to get that experience under my belt first. Wouldn’t you agree?

Thank you!

1 Like

I have Mongoose experience as well and I’m happy to help contribute to this. Any good starting points? Or just look at how postgres is working and reverse engineer? :joy:

@hyliancoder welcome to Redwood! Admittedly, my enthusiasm for this has not correlated with time and effort. I think a POC is valuable and would get a lot of community interest/feedback/attention. So if you’re interested, I’d be very happy to help as I can!

The main reason for attempting a specific integration is that Redwood uses Prisma for the DB connection/query/migration layer. It’s not required, but it sure is handy. Prisma2 was released earlier this year and so far only supports SQL-based DBs. MongoDB is coming. However, my guess is that we won’t see it until mid-2021.

If you haven’t yet, do take a look at the Redwood Tutorial — especially the “Getting Dynamic” section.

Next up would be looking at some examples of other Redwood DB integrations that don’t use Prisma:

  • This is a (very early) example with Neo4j
  • More recent example with FuanaDB

Sketching out an implementation:

  • Redwood currently instantiates the Prisma Client in api/src/lib/db.js It makes sense to use this for MongoDB client setup
  • In the near-term, we’ll be renaming api/prisma as api/db. Makes sense do use that directory structure for this as well and have schema related files in that directory
  • I’m partial to attempting the native Mongo driver. But if you’re familiar with Mongoose, that makes sense to try first
  • Ideally, there would be a nice “local dev setup” and seamless deploy. But, again, for a POC you could just connect to something like Atlas and not worry about the local setup.
  • Lastly, Redwood :heart:making use of the CLI for workflow, e.g. rw db save... up... seed. I don’t think a POC needs to include going this far, but it might be interesting to consider what the workflow might/could be and, if applicable, add some package.json scripts.
    • note: if you do want to try things like the Mongo native schema solution, this type of CLI/Script workflow could come in handy

Thoughts/questions/interested??

1 Like

That helps! Thanks for taking the time to write that up. I think that’s a good starting place, I’ll let you know if I have questions along the way (I’m sure I’ll have plenty)

1 Like

forgot to say as well, as far as “I’m partial to attempting the native Mongo driver. But if you’re familiar with Mongoose, that makes sense to try first” is concerned, I get you now, you don’t want a api > mongoose > mongo setup if you can just have a api > mongo flow.

I thought Mongoose was the preferred one since it was Option 1 on first reading your comment haha.

I’m completely willing to try native MongoDB first and see if it has any pitfalls. As far as Indexing, you cant type it via the field like you can in Mongoose via:

const User = new Schema({
    name: { type: String, index: true }
})

and instead has to be done on the collection level:

const createAscendingIndex = function(db, callback) {
  // Get the users collection
  const collection = db.collection('users');
  // Create the index
  collection.createIndex(
    { name : 1 }, function(err, result) {
    console.log(result);
    callback(result);
  });
};

so it would need to be something that ran after the model/collection that looks for the indexing happening in the api, and if it does, then stick that function at the end of the model
or
make a big function of all indexes needed schema-wide added at the end.

but due to separation of concerns, im more partial to adding it per model/collection, but obviously just my opinion on that part :joy:

^^ yes, exactly! And sorry about the confusion from the number list – prioritization was not (intentionally) implied :man_facepalming:

Oh my, that’s some ugly code for creating the index. Agreed about adding per collection. If this ends up having some legs, maybe we could think about adding a helper/utility exported from db.js

All that said, go for it! One idea for a POC is to see how/if Mongo could be used with the Redwood Tutorial specifically for blog post CRUD. But maybe that’s too ambitious for a first step.

Lastly, I’ll be offline this Friday until Nov 12th. Will catch up when I’m back. No urgency or pressure on anything. Just didn’t want you to be waiting on me and wonder what happened.

1 Like

All that said, go for it! One idea for a POC is to see how/if Mongo could be used with the Redwood Tutorial specifically for blog post CRUD. But maybe that’s too ambitious for a first step.

If someone wanted to scale that back I’d recommend just setting it up so there’s some really simple seed data in the database and Redwood is just rendering that out so you’re only worrying about reads. That’s how I started out with FaunaDB and now we’re expanding out and figuring out how to do the rest of the CRUD actions.

2 Likes

I appreciate all the answers and the heads up!

1 Like

@hyliancoder hi there! I’m back in the saddle and checking on things. Available next week if there’s anything you want to kick around. No pressure either way.

I think using GraphQL Compose with the Mongoose plugin could be a great way to support MongoDB. Being able to lean on conventions to generate the schema and resolvers from Mongoose models could be very helpful in reducing boilerplate, while being flexible enough to allow the types and resolvers to be tweaked as needed. Gatsby is also using GraphQL Compose to generate their types.

1 Like

Hi @corydeppen Welcome to Redwood! And thanks for giving this thread a much-needed nudge.

Those options look interesting for sure. Just took a quick look and curious about a few things:

  • is this in addition to creating a data model with mongoose or could it possibly replace it? I saw that it utilizes the model if you already have but wondering if you could just use this as well for model + SDL + Types
  • do you know how this handles creating/composing the SDL?
  • Redwood handles resolvers for you when creating it’s GraphQL API function. Wondering out loud how/if this is compatible. Do you have any initial guesses?

Hi @thedavid i can provide a little bit more information about core concepts of graphql-compose.

graphql-compose – is a core plugin that provides a lot of sugar for schema creation. It supports SDL first & code-first approaches for graphql schema construction. For example, you may use SDL for some type creation and then switch to code approach https://graphql-compose.github.io/docs/api/SchemaComposer.html#addtypedefs

Graphql-compose allows to call addTypeDefs() and addResolveMethods() as many times as you need, before you call buildSchema() .

- import { makeExecutableSchema } from 'graphql-tools';
+ import { schemaComposer } from 'graphql-compose';

- export const schema = makeExecutableSchema({
-  typeDefs,
-  resolvers,
- });

+ schemaComposer.addTypeDefs(typeDefs);
+ schemaComposer.addResolveMethods(resolvers);

+ export const schema = schemaComposer.buildSchema();

When you call addTypeDefs it will create TypeComposer objects which allow modifying types (add, remove fields & args). So when you made all modification & schema generation steps you need to call schemaComposer.buildSchema() for creation GraphQLSchema instance which will work with apollo-server or graphql-express.

So graphql-compose was created for schema generation. For example you have some models (e.g. mongoose) and then you may traverse their schemas and call graphql-compose methods for creating graphql types. I started using this approach 3 years ago and from that time was created graphql-compose-mongoose package which uses mongoose models as source and as output provides for you graphql types with different resolvers (find, create, update and other resolvers). Also when graphql-compose-mongoose generates for you types from models and you may remove any sensitive fields (eg password) and add new fields and relation with any other data sources.

On top of graphql-compose I’ve created a lot of different plugins:

  • graphql-compose-mongoose – generates types & resolvers from mongoose models
  • graphql-compose-elasticsearch – generates types & search resolver from elastic mapping
  • graphql-compose-json – generates types from JSON objects
  • graphql-compose-aws – generates graphql api from AWS cli schema files
  • graphql-compose-bullmq – generates API for bullmq
  • and of course, you may create any your own type generator on top of graphql-compose

And the last most interesting tool which we use internally for almost 1 year is https://github.com/graphql-compose/graphql-compose-modules Sorry but it still does not have documentation. But you may see tests or example. This tool creates schema from folder structure – it scans some folder and creates schema for them. It was inspired by NextJS, how it uses page/ folder for routing creation.


Redwood handles resolvers for you when creating it’s GraphQL API function. Wondering out loud how/if this is compatible. Do you have any initial guesses?

David, can you provide a link to your resolvers and I can see how graphql-compose can be used in your case.

2 Likes

Thanks for joining the conversation @nodkz! And great work on graphql-compose — wow, there’s a lot of functionality under the hood. :rocket:

This definitely reinforces that there’s an interesting path for an experiment using Mongoose + graphql-compose-mongoose.

Redwood’s GraphQL API has a unique design that automatically maps resolvers from Redwood Services to SDL. If it’s of interest, here’s more information about how this works:

Another reference example is this Forum Thread about using FaunaDB with Redwood. Take a look at the code examples for:

  • api/src/graphql/posts.sdl.js
  • api/src/lib/db.js
  • api/src/services/posts/posts.js
  • api/src/functions/graphql.js

Seems like we could be close to having all the Mongo pieces we’d need? Again, I’m just not sure how mapping the resolvers would work out (yet).

I wouldn’t get too excited yet, but there’s a tentative plan to release a design proposal for Mongo support in Prisma 2.16. They emphasize that this is just a design proposal and the implementation itself will take much longer. Not sure what that means, but I’ll be curious to see what they’ve got.

1 Like

If anyone wants to get involved, the Prisma team is accepting applications for user testing their MongoDB driver. There’s also an actual, totally real implementation by Gautam Singh who rolled his own solution with Prisma and Keystone. Not sure how easy that would be to port over to Redwood, but it’s at least a starting point if anyone is in desperate need of Mongo.

1 Like

Using MongoDB for the Redwood Tutorial Project

This project (deployed on Netlify) is using the new Prisma experimental connector. Check out @ajcwebdev’s comment above for a link to the Early Access Program if you want to try it out :rocket:

1 Like

A time for the double-rocket if there ever were one :rocket::rocket:

1 Like