Recommendations for MongoDB Driver and Schema solutions?

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 SchemaComposer · graphql-compose

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 GitHub - 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

MongoDB support is now in Preview mode and seems to be working out of the box with the scaffold command. If you’ve been waiting on Mongo support for a while I think now is a good time to start running experiments with your own Redwood app as Mongo support will be getting to general availability sometime in the next few months/towards the end of this year.

1 Like

Status of RedwoodJS and MongoDB as of Early 2022

It’s been a wild journey, but Prisma support for MongoDB is coming along nicely. Thankfully we never had to do any of the three things David suggested a year and a half ago at the beginning of this post, which were:

  • Use MongooseJS
  • Connect to the MongoDB NodeJS Driver
  • Think harder about it

However, since all of these things (along with Realm) are still things that someone could conceivably do with enough determination, we should clear up why using Prisma directly is more favorable.

Should You Connect to MongoDB with Realm?

It is absolutely true that anything exposed through a GraphQL endpoint can be queried from Redwood’s API in a straightforward manner with something like node-fetch or graphql-request. This is a useful way to bring in data from a third party service. You can ignore Prisma entirely, even deleting the Prisma folder containing your database schema.

But in most cases it’s not really a good idea to do this. I know this from experience, as I’ve done this on a number of example applications with tools such as Fauna and StepZen. Doing so means you leave behind the Prisma ORM entirely as your primary database tool and instead only query through a GraphQL API.

Problems with Extracting Prisma

There are two main reasons why circumventing Prisma entirely is usually a bad idea:

  • You lose out on a lot of the functionality of Redwood’s CRUD scaffolding capabilities since you aren’t building from a Prisma model.
  • Depending on what database is exposed through that endpoint and how the data is structured, GraphQL can be a sub-optimal query language.
    • This isn’t because GraphQL is bad (it pays my bills actually).
    • However, it can be limiting in comparison to the native query languages these databases actually contain.
    • In this case that query language is MQL, the MongoDB Query Language.

What If I Already Know and Love Mongoose?

When this post was originally written in October 2020, for developers who had not previously worked with MongoDB, Realm was likely the simplest way to connect to a Mongo database from a Redwood app.

Having a GraphQL interface allows the developer to almost completely ignore the underlying database schema and the concept of collections. For others however, such as many who’ve posted in this forum conversation, they already knew alternative means to query a Mongo database.

But now that Prisma in 2021 has officially added support for MongoDB, you can use MongoDB in your Redwood project as your entire backend, scaffold commands included. While still a layer of abstraction removed from MQL, it is a full ORM closer in spirit to Mongoose.

Still In Progress

Unfortunately, while this is possible today it is lacking currently in proper Redwood documentation. All the material is out there for those who are determined enough to piece it together but there isn’t an end to end tutorial yet.

However, if you are interested in using RedwoodJS and MongoDB today and want to provide early feedback, we have a cookbook in the works along with an open issue.

Relevant Prisma Links

Relevant Redwood Links

1 Like

MongoDB is now Generally Available as of Prisma v3.12.0 :partying_face: :tada:

To celebrate the release there will be a launch week later this month:

Check out the blog announcement here:

1 Like

Wow, that there is a big deal.

We should definitely promote this from our side.

I am super excited about this with the Redwood 1.0 launch week and now the Prisma - MongoDb launch week. So, I wanted to do some testing after I watched @thedavid showing how to develop apps with Redwood and Storybook. Great video. I’m looking into porting my app to Redwood but that’s another interesting story.

I attended the workshop today on the Prisma - mongoDB and tried to build a model with an embedded document. And then run the ‘yarn rw g scaffold admin/user’ command to build out all the code in Redwood. Unfortunately it gave me the following error:
‘No schema definition found for Profile in schema.prisma file’

The thing is that the type def for ‘Profile’ is there. The schema is the one they used in the tutorial. Task 14.

Is it a problem in the Redwood scaffolding generator? Or something else?
I need to run the scaffold command to get all that code and the GraphQL endpoints and such, right?

@emelleby All of that sounds exciting! Welcome to the community — I hope you find it a helpful, vibrant place to support your endeavor in porting your app. Please do check out the weekly Makers Hour and Office Hours events we host in Discord on Wednesdays.

Scaffolding does work with MongoDB. Assuming this is your schema with two models:

model User {
  id      String   @id @default(auto()) @map("_id") @db.ObjectId
  name    String?
  email   String   @unique
  profile Profile?
  posts   Post[]
}

model Post {
  id        String  @id @default(auto()) @map("_id") @db.ObjectId
  title     String
  content   String?
  published Boolean @default(false)
  author    User?   @relation(fields: [authorId], references: [id])
  authorId  String?
}

…a few things could be going on:

  1. do you have an existing model for Profile? If not, it will throw.
  2. did you run yarn rw prisma migrate dev before running the scaffold generator?
  3. AH, you have a relation in the schema — if you want to use relations with generators you’ll need to step through the process. See this “Prisma Relations and Redwood’s Generators” documentation for help.

So, Redwood generators don’t work with embedded documents according to Tasan Ishmam in this video. RedwoodJS 1.0 Meetup: April 2022 - YouTube

And you can’t run a migration as MongoDB doesn’t support that.

Bottom line: You will have to manually write the code for embedded document support with Prisma and Redwood.

What I did as an alternative is used external tools like typegraphql-prisma it has almost complete abstraction of prisma functionality into graphql, I just get the generated gql and add it in sdl files in redwoodjs

We are currently looking at an option to ren a Redwood app with the api and the web side. We are using MongoDB Atlas as our database and Realm as our backend. Realm provides a GraphQL api on the data.

What is the best solution to implement the two APIs side by side. Use the Atlas/Realm for some data fetching and the Prisma/Redwood API for some.

We are thinking to use the redwoodApolloProvider which is built in to do this, but will there be any conflicts? Any thoughts on this @ajcwebdev ?

Hey @emelleby, thanks for reaching out! That’s super exciting that you’ll be checking out the Mongo option with Redwood.

There’s a couple different ways to think about this, but my first question would be around key management. I’m not super familiar with Realm, but do you have any sort of API key that would need to be hidden from the client?

That will decide how exactly you want to connect to the Realm API and whether you want to do it from the frontend with Apollo or through the backend if you have API keys you need to mask.

The user needs to be authenticated. We are working on implementing Clerk into a Redwood app. And Clerk will provide a JWT that will authenticate to the Realm API.

Thanks.

Okay, that should work. I feel like if you had just started with Mongo Atlas and plugged that into Prisma without Realm that might make more sense overall because right now you’re going to be mostly bypassing Redwood’s API. But there’s no real reason why you can’t do that, it just might make it harder to test the API and use generator commands in the long run.

It is a bit hard to work with Prisma, Redwood and MongoDB when you have nested/embedded documents in MongoDB. Redwood does not generate any SDLs for you in this case as the generators are not capable. This is why we want to use the Realm API which is already working for us.

But what is the best way to do it is the question. Will I be able to use the redwoodApolloProvider with both endpoints? Or will Realm hijack the apolloClient?

I’m not sure if I’m making any sense here. I guess I just have to try things out.

Ahh okay yeah, I understand your question now. If you query a GraphQL endpoint from a service then you can have the frontend pick it up through a cell without any problem, but if I’m being honest I have never tried what you’re suggesting so I’m not sure what will be the best way to accomplish that without just ignoring the Redwood API entirely.