@thedavid (David Price ) posted a new topic, subject "What DBs does Redwood Support?". It read:

   RedwoodJS uses Prisma2 as it's GraphQL provider. ~~Prisma2 is in development (seeisprisma2ready)~~ and currently supports relational databases, e.g. SQL.
    
    _Note: supporting NoSQL and other DBs, including serverless, is definitely on the Prisma roadmap._
    
    **Here is the current list:**  
    _link updated August 2020_
    
    Prisma
    
    ### Databases supported by Prisma
    
    This page lists all the databases and their versions that are supported by Prisma.

Then @lvl99 (Matt Scheurich) said

    I'm curious as well! What about other database-like things, e.g. contentful, prismic, firebase, etc.?

Then @thedavid (David Price ) said

    Although I haven't personally implemented each of those items in your list, this question gets to an important, powerful aspect of Redwood's GraphQL API:
    
      * using a singular API, you are not limited to DBs — you can integrate with _any_ other API including storage, services, etc.
    
    
    
    Within the app, this means you're not locked into just a “web/” side in Redwood. Conceivably you'll be able to have “mobile/”, “desktop/”, etc. all within the monorepo and all using the singular “api/”.
    
    And if you want to use Redwood's GraphQL API to connect to AWS S3, send emails via Sendgrid, get content via Contentful, etc., you can do that, too.
    
    We don't have any examples yet, but I'd encourage people to give this a try and keep us posted on their progress and questions. RedwoodJS uses Apollo GraphQL, so that's the place to start digging in.

To which @lvl99 (Matt Scheurich) replied

    I've started looking at Apollo Server and it advertises that you can combine multiple GraphQL APIs into the one. If I were to do custom API adapters, where would I start looking for how to do that in Redwood? I've not used Prisma before and got a bit confused with this part:
    [code] 
        datasource DS {
          provider = "sqlite"
          url = env("DATABASE_URL")
        }
        
        generator photonjs {
          provider = "prisma-client-js"
          binaryTargets = env("BINARY_TARGET")
        }
        
    [/code]
    
    Since my app uses Firebase for user authentication and content managed via Prismic plus some other third party data sources (varying GraphQL and REST APIs) it'd be interesting to see how to stitch them all together within a unified Redwood API.

So @thedavid (David Price ) replied

    So the file you're referencing above, `schema.prisma`, is specific to Prisma2, which is used by Redwood for SQL database support (as I mentioned in the first post of this topic). Basically you won't work in the `api/prisma/` directory. Instead you'll be in the `api/src/`directory.
    
    For something like this you will need to write your own SDL and Services (effectively resolver functions). The difference is that the functions in your services won't talk to the database. For example, this is a snippet from the Tutorial `api/src/services/posts/posts.js`:
    [code] 
        export const posts = () => {
          return db.post.findMany()
        }
        
        ...
        
    [/code]
    
    The `db.` above is specific to the database (via the Prisma2 setup), and this is the function behind the query for all posts in `posts.sdl.js `. In the case of integrating with Sendgrid to send mail, for example, the `db.` would instead be something like `sendgrid.`. And the function body would be specific to something like sending an email.
    
    Also to note, just because our built-in support is currently for MySQL, PostgreSQL, and SQLite, there's nothing blocking you from creating your own GraphQL queries, mutations, and resolvers for other databases like Firebase, MongoDB, Fauna, etc. You just need to manually write the SDL and service functions.
    
    There's definitely some complexity here. But I hope you have enough to at least explore a bit and see what's possible.
    
    Some resources that might be of help to learn more about GraphQL specifically:
    
      * Introduction to GraphQL
      * React + Apollo Client Tutorial
      * _Haven't tried this one, but it looked like it has potential_ \--> " GraphQL File Uploads with React Hooks, TypeScript & Amazon S3"

@sam (Sam Weaver) replied

    The idea of linking in multiple APIs into the same GraphQL schema gives me some strong Gatsby / Gridsome vibes. I wonder if it would be useful to add support to just drop Gatsby plugins (which already exist for sites like Contentful, etc) into Redwood, to provide access to these APIs without having to reimplement this thing again and again.

After which, @thedavid (David Price ) added

    Hi @sam Yes indeed some similar vibes 
    
    I'm not familiar with Gridsome, but for Gatsby I do know there's a lot going on under the hood to implement GraphQL given the unique framework design. My suspicion is that there'd be redundant complexity in the way, effectively “wrapping a wrapper”.
    
    Given our roadmap of core features we've yet to build for Redwood, I can't foresee us getting to experiment with this any time soon. But we'd welcome a POC and can definitely offer feedback/direction along the way. Just keep us posted if that's something you're able to try.

To which @ajcwebdev (Anthony Campolo) replied

    Wondering if anyone has tried to deploy a Redwood app with something aside from Heroku Postgres as detailed in the tutorial? I saw some discussion around deploying without a database and some limitations around AWS DBs.
    
    I'm going to be working on building a Redwood project with Fauna over the next two weeks and was hoping to get some tips on any gotchas that might be nancy31@example.net. As far as I can tell there's been a lot of talk about getting Redwood to work with NoSQL DBs but nothing concrete yet.

So @thedavid (David Price ) replied

    Hey Anthony! I don't know of too many other custom DB integrations besides this one: Using Redwood with Neo4j Database
    
    At this time, and I'm guessing you know, Fauna is not supported by Prisma (yet). So you'll have to setup your own connection, which is definitely possible. Please do start a Forum topic and keep us posted as you go – there's a lot of interest in Fauna and I'm sure a lot of people will be curious to both help and learn from your experiment.
    
    I know people are using Redwood currently with DigitalOcean and AWS. I haven't heard of anyone using Azure DB or Google Cloud DB. But as long as it's relational (and not MSQL) it is supported by Prisma.
    
    Personally, I'm excited about MongoDB support from Prisma as I'm a big fan of the MongoDB Atlas service.

Then @kimadeline (Kim-Adeline Miguel) said

    thedavid:
    
    > I haven't heard of anyone using Azure DB
    
    I tried integrating the tutorial blog post app with Azure for Postgres, at first glance it works well  Haven't done anything prod-worthy with it, but at least I know it's possible  I basically followed the Deployment section of the tutorial with a few Azure-specific notes here and there (thank you for writing such a well-detailed tutorial! )

@thedavid (David Price ) replied

    Nice! Thanks for the update and sounds like progress 
    
    Curious if you tried (or if there's an option) to configure anything in front of Azure Postgres for handling connection pooling/load? Here's the RW related Doc: https://redwoodjs.com/docs/local-postgres-setup
    
    I'm no expert, but the gist is that in a serverless environment the front-end connections could spin up an unlimited number of connections and slam the DB.
    
    People using DigitalOcean have said PG Bouncer is working really well. On AWS is the Amazon RDS Proxy.
    
    Does it look like Azure provides something similar?

After which, @kimadeline (Kim-Adeline Miguel) added

    Nothing broke when I added the `connection_limit=1` parameter, but I haven't tried opening multiple connections to the database either 
    
    It doesn't seem like Azure provides a service similar to Amazon RDS Proxy (yet). Actually, I found a tutorial for setting up PgBouncer for Azure DB for PostgreSQL  and Citus mentions it as their preferred connection pooler in this blog post, back from before they became part of Azure's Postgres solutions.

After which, @thedavid (David Price ) added

    Ah, good to know. And thanks for looking into it! I don't think it's needed right now by any means. But once Azure seems to be working for Redwood deploy then looking into connection pooling could be a good follow-on step.
    
    Hope all's well. And have a good weekend!

@dthyresson (David Thyresson) replied

    ajcwebdev:
    
    > I'm going to be working on building a Redwood project with Fauna over the next two weeks and was hoping to get some tips on any gotchas that might be coming at me
    
    Hi @ajcwebdev. Curious how Fauna + RW is working out?
    
    I've given Fauna some thoughts and wonder if you have had the same.
    
    RW's web side talks to the api side over graphql. Cool.
    
    The api side can talk to datastores via services + sdl. Also cool.
    
    Out of the box, Prisma is supported since there is a readily available db client to import and write queries/mutations.
    
    But, a service is a service. My SDL can define the queries, but I don't have to use the Prisma db client. I could use the `Contentful SDK` – or call another graphql endpoint (Hasura … or Fauna … or Contentful for that matter) using `graphql-request`.
    
    I've shared this example here before, but my I made an app a year or so ago where 8 year old niece uses Contentful to keep track of little Disney Princess cupcake characters she build from pieces of a board game. The SDL is:
    [code] 
        import gql from 'graphql-tag'
        
        export const schema = gql`
          type Cupcake {
            id: String!
            name: String!
            description: String!
            price: Float
            rating: Int
            slug: String!
            photos: [ContentfulAsset]
          }
          type Query {
            cupcakes: [Cupcake!]!
            cupcake(id: String!): Cupcake!
          }
        `
        
    [/code]
    
    and the service that uses their SDK is:
    [code] 
        import { createClient } from 'contentful'
        
        const client = createClient({
          space: process.env.CONTENTFUL_SPACE,
          accessToken: process.env.CONTENTFUL_DELIVERY_API_KEY,
        })
        
        const renderAsset = (fields) => {
          return { title: fields.title, file: fields.file }
        }
        
        const renderAssets = (assets) => {
          return assets.map((asset) => renderAsset(asset.fields))
        }
        
        const renderEntry = (entry) => {
          return {
            id: entry.sys.id,
            name: entry.fields.name,
            description: entry.fields.description,
            price: entry.fields.price,
            rating: entry.fields.rating,
            slug: entry.fields.slug,
            photos: renderAssets(entry.fields.photos),
          }
        }
        
        export const cupcakes = async () => {
          const response = await client.getEntries({
            content_type: 'cupcake',
            limit: 1000,
            order: 'fields.name',
          })
        
          return response.items.map((entry) => renderEntry(entry))
        }
        
        export const cupcake = async ({ id }) => {
          const entry = await client.getEntry(id)
        
          return renderEntry(entry)
        }
        
    [/code]
    
    and then I can use RW cells just as I would if I was querying a Prisma Postgres database:
    [code] 
        import Cupcake from 'src/components/Cupcake'
        
        export const QUERY = gql`
          query {
            cupcakes {
              id
              name
              description
              price
              rating
              slug
              photos {
                title
                file {
                  url
                }
              }
            }
          }
        `
        
        export const Loading = () => {
          return (
            <Stack>
              <Box mb={6} maxW="sm" overflow="hidden">
                <Box p="6">
                  <Skeleton height="20px" my="10px" />
                </Box>
              </Box>
              <Box mb={6} maxW="sm" overflow="hidden">
                <Box p="6">
                  <Skeleton height="20px" my="10px" />
                </Box>
              </Box>
              <Box mb={6} maxW="sm" overflow="hidden">
                <Box p="6">
                  <Skeleton height="20px" my="10px" />
                </Box>
              </Box>
            </Stack>
          )
        }
        
        export const Empty = () => <div>Empty</div>
        
        export const Failure = ({ error }) => <div>Error: {error.message}</div>
        
        export const Success = ({ cupcakes }) => {
          return cupcakes.map((cupcake) => (
            <Cupcake key={cupcake.id} cupcake={cupcake}></Cupcake>
          ))
        }
        
    [/code]
    
    Or, if I wanted to call another GraphQL endpoint, in this case a PG-backed view served by Hasura for “daily story counts” my SDL is:
    [code] 
        import gql from 'graphql-tag'
        
        export const schema = gql`
          type Calendar {
            day: String!
            value: Int!
          }
          type Query {
            dailyStoryCounts: [Calendar!]!
          }
        `
        
    [/code]
    
    I then have a Hasura client (just like a lib/db)
    [code] 
        import { GraphQLClient } from 'graphql-request'
        
        export const request = async (
          query = {},
          domain = process.env.HASURA_DOMAIN
        ) => {
          const endpoint = `https://${domain}/v1/graphql`
        
          const graphQLClient = new GraphQLClient(endpoint, {
            headers: {
              'x-hasura-admin-secret': process.env.HASURA_KEY,
            },
          })
        
          try {
            return await graphQLClient.request(query)
          } catch (error) {
            console.log(error)
            return error
          }
        }
        
    [/code]
    
    Then my service uses that client to fetch:
    [code] 
        import { request } from 'src/lib/hasuraClient'
        
        export const dailyStoryCounts = async () => {
          const query = `
          {
            dailyStoryCounts: calendar {
              day: date
              value
            }
          }
         `
          const data = await request(query, process.env.HASURA_DOMAIN)
        
          return data['dailyStoryCounts']
        }
        
    [/code]
    
    and my cells is normal and can render a nice calendar chart:
    [code] 
        import { Box } from '@chakra-ui/core'
        import { ResponsiveCalendar } from '@nivo/calendar'
        
        export const QUERY = gql`
          query {
            dailyStoryCounts {
              day
              value
            }
          }
        `
        
        export const Loading = () => <div>Loading...</div>
        
        export const Empty = () => <div>Empty</div>
        
        export const Failure = ({ error }) => <div>Error: {error.message}</div>
        
        export const Success = ({ dailyStoryCounts }) => {
          const firstDay = dailyStoryCounts[0].day
          const lastDay = dailyStoryCounts[dailyStoryCounts.length - 1].day
        
          return (
            <Box height="600px" width="100%">
              <ResponsiveCalendar
                data={dailyStoryCounts}
                from={firstDay}
                to={lastDay}
                emptyColor="#eeeeee"
                colors={['#61cdbb', '#97e3d5', '#e8c1a0', '#f47560']}
                margin={{ top: 40, right: 40, bottom: 40, left: 40 }}
                yearSpacing={40}
                monthBorderColor="#ffffff"
                dayBorderWidth={2}
                dayBorderColor="#ffffff"
                legends={[
                  {
                    anchor: 'bottom-right',
                    direction: 'row',
                    translateY: 36,
                    itemCount: 4,
                    itemWidth: 42,
                    itemHeight: 36,
                    itemsSpacing: 14,
                    itemDirection: 'right-to-left',
                  },
                ]}
              />
            </Box>
          )
        }
        
    [/code]
    
    Screen Shot nancy31@example.net×226 3.85 KB
    
    (note: I turned off data in July)
    
    Ok. That was long winded, I know.
    
    But, to implement Fauna right now I would either:
    
      * use the Fauna client and write FQL (ie, the Contentful SDK approach)
      * make a gql client and write graphql against Fauna (the Hasura approach)
    
    
    
    What I don't think I would want is for the web to call Fauna directly or RW's graphql to somehow relay the gql to Fauna. Do I? Don't think so, but I have not experimented.
    
    But what I think is super super cool is that I think if I had services that talked to Contentful (cupcakes) and Hasura (stories) and Prisma/Postgres (users), I am pretty sure I could make a single graphql request from a cell like
    [code] 
           query {
             cupcakes {
               id
               name
             }
         
            stories {
             id
             title
            }
        
            users {
              id 
              email
            }
        }
        
    [/code]
    
    And I could render all the data from three different sources in a Dashboard cell like:
    [code] 
        export const Success = ({ cupcakes, stories, users }) => {
        }
        
    [/code]
    
    And if the id's somehow matched, I could probably even filter: give me stories this user wrote about these cupcakes.
    
    That's really really cool.
    
    BTW - this is Monty: “Monty likes to play in the woods to hide from his sister Minty.”

So @ajcwebdev (Anthony Campolo) replied

    Awesome, that was very, very helpful, and definitely not long winded. My goal here is to create a tutorial for Fauna to get Fauna users up and running with Redwood as easily as possible. So I think the FQL approach is more appealing to me here since we'll be more on Fauna's turf so to speak.
    
    I'd want to explore the gql client approach as well because that would be more agnostic. As David was saying we'll want to figure out Mongo and other DBs, and since Fauna is a document store there's cross-over there, but the query languages are totally different.

@dthyresson (David Thyresson) replied

    ajcwebdev:
    
    > I think the FQL approach is more appealing to me
    
    Same here.
    
    FQL is really strange (least to me coming from SQL) at first, but I got used to it for basic queries. Figuring out the equivalent of joins still makes my head hurt a bit.
    
    Plus (I think) to support GraphQL in Fauna one has to create a schema – so that would not be the “up and running with Redwood as easily as possible” case.
    
    That reminds me – looking at some of the FQL I did – pagination. I need to explore how to do that in RW.

So @ajcwebdev (Anthony Campolo) replied

    Yeah I'm always hesitant to invest in learning any DSL but it's hard to avoid with databases, even those that follow the SQL spec end up with slightly different implementations since the spec is ambiguous.
    
    Thankfully Fauna has really invested in their docs and blog articles, I'm going through this series right now to get up to speed. Not sure how deep you've gotten into their material but they've got a section on pagination that should be helpful.

After which, @ajcwebdev (Anthony Campolo) added

    Just a heads up, @thedavid, your link to prisma2's supported database list in the first post of this Topic is a dead link and gives you a redirect to Prisma's docs. If you click the “Edit this page on Github” link you'll find the new place on Github the content lives.
    
    Looks like they did a rearrangement cause they originally had a `docs` folder inside the `prisma` repo but wanted to have a dedicated `docs` repo by itself.

Then @thedavid (David Price ) said

    Thanks for the heads up. Updated OP with new website page.

@databrecht (Brecht De Rooms) replied

    Wanted to add this here to complete the story since recently a guide: https://fauna.com/blog/building-a-minimum-viable-stack-with-redwoodjs-and-faunadb  
    came out on how to use RedwoodJS with FaunaDB.   
    The guide bypasses Prisma if I understood correctly.

To which @ajcwebdev (Anthony Campolo) replied

    Hey Brecht, thanks for the link! You are correct, the project has you delete all the Prisma directories and code and we query the Fauna GraphQL API directly. I had a blast making the project and the whole Fauna team was incredible to work with.

After which, @ajcwebdev (Anthony Campolo) added

    I recently did some research into what the situation was with MongoDB and Prisma that wasn't directly about Redwood but should still be pretty relevant to the discussion here. I asked some big picture questions and Nikolas Burke gave a really great response that's worth sharing here.
    
    TL:DR Prisma+Mongo is super duper hard and learn Rust
    
    * * *
    
    Hey Anthony  thank you so much for this great writeup and for summarizing the comments from the issue  We are very aware that people are eagerly waiting for MongoDB support in Prisma 2! I want to shed some light on the current situation and how we are currently thinking about a MongoDB connector by responding to your questions.
    
    > Does Prisma need anything else from MongoDB to implement a connector or is the MongoDB Rust driver good to go?
    
    As far as I'm aware, we don't need anything else from MongoDB on a technical level.
    
    > Is anyone at Prisma currently working on a MongoDB connector or accountable for tracking its progress?
    
    We are not actively working on a MongoDB connector at the moment. This is also reflected on our roadmap.
    
    Note that there are a few technical prerequisites for the MongoDB connector, such as the ability to use native database types in the Prisma schema (the good news is that this is under active development and likely to be released within the next 2-3 months). Another feature that we need to get done before we can get serious about a MongoDB connector is Prisma Migrate. Migrations for SQL and NoSQL databases mean _very_ different things. We need to be confident about our solution for SQL databases before we can “afford” expanding to NoSQL ones.
    
    > If not what can contributors do to help Prisma out?
    
    Unfortunately I believe there's not much that contributors can do at this point, unless they have _a lot_ of free time and come equipped with some very solid knowledge about Rust, JS/TS and databases altogether.
    
    While Prisma is open source, the software we're building is extremely complex. The onboarding processs for new developers who need to get into our codebase typically taskes several days/weeks until there's a level of familiarity where they can independently contribute. In that sense, it seems practically impossible that somebody who's not part of our engineering orgnization would be able to grasp the complexity of the codebase and would be able to contribute. We are aware that this is not ideal though and one of our internal engineering initiatives for the next months is to start better documenting the internals of Prisma – hopefully this will make it easier for external folks to contribute in the future!
    
    However, I actually think that the complexity of the codebase is not the main problem in this case. The bigger one is that there a lot of unknowns and unresolved “product questions”. The Prisma schema as well as the Prisma Client API are currently optimized for relational databases. MongoDB brings a new database paradigm and we'll need to figure out how this can play nicely together with our existing tools.
    
    **So, what can you do to help?**
    
    Talk to our product team! Share your thoughts about the MongoDB connector with the product team directly or keep commenting in the GitHub issue. Your input will be the foundation for what we're building, so if you're eagerly waiting for the MongoDB connector, th best thing you can do right now is help us figure out what it actually should look like and how it should work.
    
    As I said, we are very aware that people want MongoDB support (so do we ), but there are a few roadblocks we need to get out of the way before we can start serious development on it.

After which, @ajcwebdev (Anthony Campolo) added

    Mongo support is getting here slowly but surely. The Prisma team is accepting applications for user testing and amazingly enough Gautam Singh has, against all odds, rolled his own solution with Prisma and Keystone.

After which, @rodocite (Rodolfo Yabut) added

    I think of the coupling with Prisma as the blocker from going full polyglot db. It's a flexible ORM/driver for a good subset of tried and true databases, but any robust app is polyglot and sources data from multiple aggregates. Moreover, not every team will buy-in on Prisma-- so even if you get it into a project, it's often running on its own and needs to compromise due to external migrations coming from another codebase.
    
    I also think that the db compatibility issue can be solved by GraphQL alone w/ aid from the framework to enhance dev experience and doesn't require DB-development chops as long as there is a robust JS driver for the DB itself.
    
    GraphQL's promise is to adapt any and all data sources into 1 easily usable and dev-experience focused pattern that can be write + read optimized. The tight binding w/ Prisma in this case somewhat undoes that because of the inflexibility in DBs. Prisma is nice because it normalizes DSL for a variety of relational DBs, but the support isn't enough and in a lot of cases, full parity probably isn't possible. The DSL philosophy is relational and may not be immediately compatible with nosql patterns as seen by the relative slow development of the MongoDB driver (which I bet is a lot like jamming a square peg into a triangle hole).
    
    If I could just fill out some core generalized boilerplate that allows me to rock n roll with any data source + multiple data sources, RW would be such an easy sell for any team. What that possibly looks like to me is a decoupled /services folder with resolvers that can access any data source I want and 1 gql schema folder where I create my SDLs without worrying about anything else but the schema.
    
    **Hey wait a minute… the framework is like 85% there!**

So @ajcwebdev (Anthony Campolo) replied

    #  Databases RedwoodJS Supports as of Early 2022
    
    Over the last two years, the amount of ways to connect to a database with Redwood and the amount of ways to deploy and host that database have increased tremendously.
    
    ###  Supported by Prisma
    
    Prisma has expanded their list of relational/SQL options and started introducing non-relational databases.
    
      * SQLite
        * Render
        * Fly
      * PostgreSQL
        * Render
        * Supabase
        * Railway
        * Fly
        * CockroachDB
        * Azure
        * Heroku
      * MySQL
        * Railway
        * PlanetScale
      * SQL Server
        * ??? 
      * MongoDB
        * Atlas
        * Railway
    
    
    
    ###  Databases with GraphQL Endpoints
    
    For databases that Prisma doesn't support, the Redwood GraphQL API can be used to query any database that exposes a GraphQL endpoint, whether the underlying database is SQL or NoSQL.
    
      * Fauna
      * Neo4j


{'source': 'discourse', 'url': 'https://community.redwoodjs.com/t/what-dbs-does-redwood-support/143', 'title': 'What DBs does Redwood Support?', 'views': 3764, 'has_accepted_answer': False, 'word_count': 4354, 'like_count': 20, 'reply_count': 13, 'participant_count': 8, 'posts': 25, 'tags': '', 'author': '@thedavid (David Price )', 'participants': '@thedavid (David Price ), @lvl99 (Matt Scheurich), @sam (Sam Weaver), @ajcwebdev (Anthony Campolo), @kimadeline (Kim-Adeline Miguel), @dthyresson (David Thyresson), @databrecht (Brecht De Rooms), @rodocite (Rodolfo Yabut)', 'image_url': ['https://rwjs-discourse.nyc3.cdn.digitaloceanspaces.com/optimized/1X/0608077b8f2a40e862bc8c3e6eb7af33137da337_2_1024x537.png'], 'created_at': '2020-03-18T16:24:10.649Z', 'last_posted_at': '2022-03-06T07:13:16.633Z'}