Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

Join us at AWS re:Invent 2024! Learn how to use MongoDB for AI use cases.
MongoDB Developer
TypeScript
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Languageschevron-right
TypeScriptchevron-right

Type Safety With Prisma & MongoDB

Jesse Hall4 min read • Published Apr 25, 2022 • Updated Aug 09, 2024
MongoDBTypeScriptJavaScript
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Did you know that Prisma now supports MongoDB? In this article, we'll take a look at how to use Prisma to connect to MongoDB.

What is Prisma?

Prisma is an open source ORM (Object Relational Mapper) for Node.js. It supports both JavaScript and TypeScript. It really shines when using TypeScript, helping you to write code that is both readable and type-safe.
If you want to hear from Nikolas Burk and Matthew Meuller of Prisma, check out this episode of the MongoDB Podcast.

Why Prisma?

Schemas help developers avoid data inconsistency issues over time. While you can define a schema at the database level within MongoDB, Prisma lets you define a schema at the application level. When using the Prisma Client, a developer gets the aid of auto-completing queries, since the Prisma Client is aware of the schema.

Data modeling

Generally, data that is accessed together should be stored together in a MongoDB database. Prisma supports using embedded documents to keep data together.
However, there may be use cases where you'll need to store related data in separate collections. To do that in MongoDB, you can include one document’s _id field in another document. In this instance, Prisma can assist you in organizing this related data and maintaining referential integrity of the data.

Prisma & MongoDB in action

We are going to take an existing example project from Prisma’s prisma-examples repository.
One of the examples is a blog content management platform. This example uses a SQLite database. We'll convert it to use MongoDB and then seed some dummy data.
If you want to see the final code, you can find it in the dedicated Github repository.

MongoDB Atlas configuration

In this article, we’ll use a MongoDB Atlas cluster. To create a free account and your first forever-free cluster, follow the Get Started with Atlas guide.

Prisma configuration

We'll first need to set up our environment variable to connect to our MongoDB Atlas database. I'll add my MongoDB Atlas connection string to a .env file.
Example:
1DATABASE_URL="mongodb+srv://<username>:<password>@<cluster>.mongodb.net/prisma?retryWrites=true&w=majority"
You can get your connection string from the Atlas dashboard.
Now, let's edit the schema.prisma file.
If you are using Visual Studio Code, be sure to install the official Prisma VS Code extension to help with formatting and auto-completion.
While you’re in VS Code, also install the official MongoDB VS Code extension to monitor your database right inside VS Code!
In the datasource db object, we'll set the provider to "mongodb" and the url to our environment variable DATABASE_URL.
For the User model, we'll need to update the id. Instead of an Int, we'll use String. We'll set the default to auto(). Since MongoDB names the id field _id, we'll map the id field to _id. Lastly, we'll tell Prisma to use the data type of ObjectId for the id field.
We'll do the same for the Post model id field. We'll also change the authorId field to String and set the data type to ObjectId.
1generator client {
2 provider = "prisma-client-js"
3}
4
5datasource db {
6 provider = "mongodb"
7 url = env("DATABASE_URL")
8}
9
10model User {
11 id String @id @default(auto()) @map("_id") @db.ObjectId
12 email String @unique
13 name String?
14 posts Post[]
15}
16
17model Post {
18 id String @id @default(auto()) @map("_id") @db.ObjectId
19 createdAt DateTime @default(now())
20 updatedAt DateTime @updatedAt
21 title String
22 content String?
23 published Boolean @default(false)
24 viewCount Int @default(0)
25 author User @relation(fields: [authorId], references: [id])
26 authorId String @db.ObjectId
27}
This schema will result in a separate User and Post collection in MongoDB. Each post will have a reference to a user.
Now that we have our schema set up, let's install our dependencies and generate our schema.
1npm install
2npx prisma generate
If you make any changes later to the schema, you'll need to run npx prisma generate again.

Create and seed the MongoDB database

Next, we need to seed our database. The repo comes with a prisma/seed.ts file with some dummy data.
So, let's run the following command to seed our database:
1npx prisma db seed
This also creates the User and Post collections that are defined in prisma/schema.prisma.

Other updates to the example code

Because we made some changes to the id data type, we'll need to update some of the example code to reflect these changes.
The updates are in the pages/api/post/[id].ts and pages/api/publish/[id].ts files.
Here's one example. We need to remove the Number() call from the reference to the id field since it is now a String.
1// BEFORE
2async function handleGET(postId, res) {
3 const post = await prisma.post.findUnique({
4 where: { id: Number(postId) },
5 include: { author: true },
6 })
7 res.json(post)
8}
9
10// AFTER
11async function handleGET(postId, res) {
12 const post = await prisma.post.findUnique({
13 where: { id: postId },
14 include: { author: true },
15 })
16 res.json(post)
17}

Awesome auto complete & IntelliSense

Example GIF showing VS Code autocomplete and IntelliSense capabilities
Notice in this file, when hovering over the post variable, VS Code knows that it is of type Post. If we just wanted a specific field from this, VS Code automatically knows which fields are included. No guessing!

Run the app

Those are all of the updates needed. We can now run the app and we should see the seed data show up.
1npm run dev
We can open the app in the browser at http://localhost:3000/.
Screencapture of the resulting application pages in the browser
From the main page, you can click on a post to see it. From there, you can delete the post.
We can go to the Drafts page to see any unpublished posts. When we click on any unpublished post, we can publish it or delete it.
The "Signup" button will allow us to add a new user to the database.
And, lastly, we can create a new post by clicking the "Create draft" button.
All of these actions are performed by the Prisma client using the API routes defined in our application.
Check out the pages/api folder to dive deeper into the API routes.

Conclusion

Prisma makes dealing with schemas in MongoDB a breeze. It especially shines when using TypeScript by making your code readable and type-safe. It also helps to manage multiple collection relationships by aiding with referential integrity.
I can see the benefit of defining your schema at the application level and will be using Prisma to connect to MongoDB in the future.
Let me know what you think in the MongoDB community.

Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Article

The Cost of Not Knowing MongoDB


Nov 11, 2024 | 23 min read
Quickstart

Getting Started With Bun and MongoDB


Jul 19, 2024 | 9 min read
Tutorial

Instant GraphQL APIs for MongoDB with Grafbase


Oct 12, 2023 | 7 min read
Tutorial

How to Deploy MongoDB Atlas with AWS CDK in TypeScript


Jan 23, 2024 | 5 min read
Table of Contents
  • What is Prisma?