How to use Prisma ORM in Next.js?

How to use Prisma ORM in Next.js?

Published 8th, November, 2022

4 min read

The world of databases not only has security in the core of its existence, but also being user-friendly and intuitive to operate. Thankfully, almost all database technologies, SQL-based or otherwise fulfil this promise.

However, the ever-expanding scope of development technologies creates a need to have something better; something that will suit their speed and efficiency.

This is where comes Prisma! An Object Relationship Model (ORM) that helps you to avoid writing complicated SQL or non-SQL syntax and is compatible with multitude of database management systems such as MySQL, Postgresql, MongoDB, Maria DB etc, supporting both REST and GraphQL APIs.

Prisma’s functionality can be ‘trisected’ into Prisma’s Query Building System, Prisma's migration system and Prisma Studio, a dedicated GUI platform to manage your databases.

Now let's move ahead and get to know more!

Getting started with Prisma

Prisma’s method of working involves creating a file that is dedicated to creating DB ‘models’ of various entities within, like you see below. The following snippets of Prisma’s database interactions have been inspired from its official website, the link to that you’ll find at the end of the article.

datasource your_db {
    db_ name = "<your database>"
    db_path = env("<your database URL>")
}

generator client {
    provider = "prisma-client-js"
}

In the above example, we begin with datasource your_db, which declares the database you are using for your project, which in this project is Postgresql.

The other half of the above snippet declares Prisma itself as a database client to the application.


model Entry {
    member_id Int @id @default(autoincrement())
    entry_title String
    entry_content String ?
        date_published Boolean @default(false)
    entry_author User ? @relation(fields: [member_id], references: [id])
    post_author_id Int ?
}

model Member {
    member_id Int @id @default(autoincrement())
    member_email String @unique
    member_name String ?
        member_entries Entry
}

In the above snippet, we have two database object models declared, which is a standard and well known practice in application development domain, across languages.

Here, model Entry has entry_id, entry_title, entry_content, date_published, Member, member_id attributes, followed by their respective data types as well as relation to other models.

After writing the schema on your own, migrate the database

prisma migrate dev --name init

Your migrations folder will look something like the following

migrations/ 
		└─ 20210312250442_init/ 
			└─ migration.sql

You can also create new fields to your schema

model Member {

    mem_id Int @id @default(autoincrement())
    job_profile String
    mem_name String
    total_entries Entries[]
}

And then you migrate this

prisma migrate dev --name added_job_title

This was just a primer on saving your database model through Prisma’s ‘migrate’ feature. To know more about this, you can refer to the first link in the ‘References’ section.

Using Prisma with various forms of Next.js

Next.js has various methods of fetching data to the front-end, which are designed to be resource and time efficient, such as

  1. getStaticProps for Static Site Generation
  2. getServerSideProps
  3. API Props
  4. Standalone Server

All the snippets below have been taken from the official Prism documentation. The link is at the end of this article.

1. getStaticProps

To accomplish Static Site Generation, the getStaticProps function in Next.js is designed to be executed at the build time. Given the ‘static’ in its name, it is suitable for apps like blogs or content media. You can write Prisma inside this function to fetch data from your databases

// Fetch all entries (in /pages/index.tsx)
  const prisma = new PrismaClient();

export async function getStaticProps() {
  const blog_entries = await prisma_obj.post.findMany();

  return {
    props: {
      blog_entries,
    },
  };
}

This will be passed to your React.js, resulting in static rendering of your page, while also loading your dynamic data.

2. getServerSideProps

The getServerSideProps function in Next.js is built for request time execution to achieve server-side rendering (SSR). Prisma can be built inside this function to query your database in order to fetch dynamic data for times such as user authentication.

// Fetch posts from authenticated user
// (in /pages/index.tsx)
const prisma = new PrismaClient();

export const getServerSideProps = async ({ req }) => {
  const token = req.headers.AUTHORIZATION;
  const userid = await getUserId(token);
  const entries = await prisma.post.findMany({
    where: {
      author: {
        id: userid,
      },
    },
  });
  return {
    props: {
      entries,
    },
  };
};

And once you get your data, you can display it with React.js

// Display list of posts (in /pages/index.tsx)
export default ({ entries }) => {
  return (
    <ul>
      {entries.map((entry) => (
        <li key={entry.id}> {entry.title} </li>
      ))}
    </ul>
  );
};

3. Standard API Interactions

Prisma works well with all widely-used APIs, especially the REST API and GraphQL API in Next.js API routes. For example

// Fetch all entries (in /pages/api/posts.ts)
const prisma = new PrismaClient();

export default async function handle(req, res) {
  const entries = await prisma.post.findMany();
  res.json(entries);
}

You can then fetch the data and display it on your Next.js page, using Next.js very own SWR library.

 // Display entries in frontend (in /pages/index.tsx)
export default function yourApp() {
  const { appData, returnError } = useSWR("/api/entries", fetcher);
  if (returnError) return <div> Error occured. </div>;
  if (!appData) return <div> Loading data..</div>;

  return (
    <ul>
      {appData.entries.map((entry) => (
        <li key={entry.id}> {entry.title} </li>
      ))}
    </ul>
  );
}

That’s all! Or is it?

Here’s an honourable mention; The standalone servers

If you are a developer and are using a test server, most of the times it’s going to be a standalone server. Just make sure that the server is running any technology that can make an API accessible to your Next.js front-end, such as HTTP or any GraphQL library, such as Express.

// Fetch all entries in an Express route
  const prisma = new PrismaClient();

app.get("/entries", async (req, res) => {
  const entries = await prisma.entry.findMany();
  res.json(entries);
});

And like before, you can fetch the data and display it in the front-end with Vercel’s SWR library

That’s all developers. Try Prisma because, who knows? Maybe it will become the next big thing on the developer’s job market. But not only for that, but also for making your programming tasks easier, Prisma fits the bill.

References:

  1. prisma
  2. prisma nextjs