DEV Community

Cover image for Querying MongoDB with Prisma and Railway
ajcwebdev
ajcwebdev

Posted on • Updated on • Originally published at ajcwebdev.com

Querying MongoDB with Prisma and Railway

Outline

All of this project's code can be found in the First Look monorepo on my GitHub.

Introduction

In this guide we will deploy a MongoDB database with Railway, add seed data to the database, connect to the database through a connection string, and create a Node script to query that seed data with Prisma Client.

Create Prisma Project

Create a blank new project and initialize a package.json.

mkdir railway-prisma-mongodb
cd railway-prisma-mongodb
yarn init -y
Enter fullscreen mode Exit fullscreen mode

Install the prisma dependencies.

yarn add @prisma/client
yarn add -D prisma
Enter fullscreen mode Exit fullscreen mode

Set type to module in package.json.

{
  "name": "railway-prisma-mongodb",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "@prisma/client": "^3.10.0"
  },
  "devDependencies": {
    "prisma": "^3.10.0"
  },
  "type": "module"
}
Enter fullscreen mode Exit fullscreen mode

Initialize Prisma Schema

prisma init scaffolds a basic Prisma project.

yarn prisma init
Enter fullscreen mode Exit fullscreen mode

The only other necessary file is index.js. This is used for running test commands against our database with the Prisma Client.

touch index.js
Enter fullscreen mode Exit fullscreen mode

Our project now has the following structure:

/
├── prisma
│   └── schema.prisma
├── .env
├── .gitignore
├── index.js
└── package.json
Enter fullscreen mode Exit fullscreen mode

Prisma Schema

Define a Post model by adding the following to the schema.prisma file.

datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["mongoDb"]
}

model Post {
  id    String @id @default(auto()) @map("_id") @db.ObjectId
  slug  String @unique
  title String
  body  String
}
Enter fullscreen mode Exit fullscreen mode

previewFeatures must be set to mongoDb in the client generator to enable MongoDB support.

Provision a MongoDB Database with Railway

There are two ways to setup a MongoDB database with Railway, through the dashboard or through the CLI.

Railway Dashboard

To use the dashboard, click dev.new and choose "Provision MongoDB."

01-railway-project-dashboard

After the database is setup click "MongoDB" on the left to see the default test database that is autogenerated.

02-mongodb-data-dashboard

Choose "Connect" to find your connection string.

03-mongodb-connection-string

Railway CLI

If you want to use the Railway CLI instead of the dashboard, first you need to install it. To verify that you successfully installed the CLI, run the following command to check the CLI version.

railway version
Enter fullscreen mode Exit fullscreen mode

Run railway login to authenticate your Railway account. If you do not have a Railway account you will be prompted to create one.

railway login
Enter fullscreen mode Exit fullscreen mode

railway init initializes a project and asks if you want to start with an empty project or a starter template. Select “Empty Project” and give your project a name.

railway init
Enter fullscreen mode Exit fullscreen mode

Run railway add and select MongoDB to add the MongoDB plugin to your Railway project.

railway add
Enter fullscreen mode Exit fullscreen mode

Connect Railway Database to Prisma Project

Return to the Railway dashboard to find your connection string.

Set Environment Variable

Inside your .env file include DATABASE_URL and set the variable to the connection string provided by Railway. Specify the database name and authentication source at the end of the connection string by adding /test?authSource=admin after the port number.

DATABASE_URL="mongodb://mongo:<PASSWORD>@containers-us-west-1.railway.app:6852/test?authSource=admin"
Enter fullscreen mode Exit fullscreen mode

Sync the schema with the database by using prisma db push.

yarn prisma db push
Enter fullscreen mode Exit fullscreen mode

Seed Database

You can also connect to the database directly with the mongosh command.

mongosh "mongodb://mongo:<PASSWORD>@containers-us-west-1.railway.app:6852"
Enter fullscreen mode Exit fullscreen mode

The database can be seeded from the Railway dashboard or through mongosh with the following seed command.

db.Post.insertOne(
  {
    slug: "first-post-slug",
    title: "First Post Title",
    body: "First post body."
  }
)
Enter fullscreen mode Exit fullscreen mode

Check the data tab in the Railway dashboard to see the data.

Generate Prisma Client

Generate the Prisma Client with the prisma generate command.

yarn prisma generate
Enter fullscreen mode Exit fullscreen mode

Create a Script to Query the Database

Add the following script to index.js to test that we can read data from our database. This function runs the findMany query on our post collection and returns all posts in the collection.

// index.js

import pkg from '@prisma/client'

const { PrismaClient } = pkg
const prisma = new PrismaClient()

async function main() {
  await prisma.$connect()

  const posts = await prisma.post.findMany()

  console.dir(posts, { depth: Infinity })
}

main()
  .catch(console.error)
  .finally(() => prisma.$disconnect())
Enter fullscreen mode Exit fullscreen mode

Run the Script

Run node index.js to execute the main function.

node index.js
Enter fullscreen mode Exit fullscreen mode

If you followed along correctly you should get the following output:

[
  {
    id: '61f369df79160504b0ee41d9',
    slug: 'first-post-slug',
    title: 'First Post Title',
    body: 'First post body.'
  }
]
Enter fullscreen mode Exit fullscreen mode

Oldest comments (9)

Collapse
 
nheindev profile image
Noah Hein

Is this your first bit of no-sql db work?

I've yet to touch mongo or any other noSQL stuff.

Collapse
 
ajcwebdev profile image
ajcwebdev

Technically Fauna is a NoSQL database so I have a decent amount of experience with that but Mongo is totally different from Fauna despite them both being NoSQL databases. The term NoSQL was more of a marketing gimmick for a handful of non-relational databases in the early 2010s than a proper category of database.

A better way to categorize databases is comparing the data model not the query language. Is it relational, document, graph, time series, etc. NoSQL just means it's not using SQL (structured query language), so every NoSQL database has it's own query language that may be completely unique to itself.

I've been slowly getting into Mongo specifically because Prisma has been adding support. We want Redwood users to be able to use Mongo if they want and still have a first class experience.

I've got two other things I've documented:

  • Can I Use MongoDB with Prisma Yet? - An article that is very, very similar to this one except with Mongo Atlas instead of Railway for hosting the database
  • redwood-mongo - A Redwood repo that's using Mongo that I may expand out into a blog post at some point
Collapse
 
shruti025 profile image
Shruti Goyal

Hey, I tried following the code but the result shows an empty array instead of what its expected to show. Can you help me out here?

Collapse
 
ajcwebdev profile image
ajcwebdev • Edited

Hey Shruti, thanks for the message! As a preview feature this is a bit of a moving target, so I appreciate the heads up. I ran through the tutorial again and was getting the same issue.

There were a couple things that I noticed were causing problems, but I believe I've now got the tutorial sorted out. Try running through it again with a fresh project and database and let me know if you are still having the same problem.

The things I changed:

  • The schema was using the deprecated dbgenerated() function, instead it should be the auto() function introduced in Prisma 3.10.0.
  • Right after setting your environment variable in .env, run yarn prisma db push. This will create a collection in the database that matches the name of the model, in this case Post.
  • The mongosh command was using db.post.insertOne instead of db.Post.insertOne causing a second collection to be created with different casing.
  • Incorrect casing on the collection may have also been a problem when seeding through the Railway dashboard, but that should also be fixed as long as you run yarn prisma db push before trying to add any data through the dashboard.

If you can't get one method of seeding to work then give the other one a try. But they should both return data if you follow the steps outlined in the article right now. Hope that helps!

Collapse
 
shruti025 profile image
Shruti Goyal

I cannot thank you enough for this. It worked! Thank you so much Anthony :D

Thread Thread
 
ajcwebdev profile image
ajcwebdev

Yay! Glad I could help 😊.

Collapse
 
gabogomezt profile image
Gabriel

This post helped me out, thanks! But now I'm getting a new error that says the following
Prisma needs to perform transactions, which requires your MongoDB server to be run as a replica set. pris.ly/d/mongodb-replica-set

Is this happening to anyone else?

Collapse
 
ajcwebdev profile image
ajcwebdev

Hey Gabriel! I haven't run through this example in a while, however @ruheni or @sabinthedev might be able to help.

Collapse
 
ruheni profile image
Ruheni Alex

Hi Gabriel 👋

To resolve this, you can use MongoDB Atlas with replica set support out of the box. Alternatively, you can also convert your standalone instance to a replica set(Guide).

Feel free to refer to the Replica set configuration page in our docs for further details and reach out if you hit a snag. 🙂