Getting started with Next.js and Prisma

October 16, 2021
views 4 min read

Lately every time I have an idea for a pet project this is usually the stack I go with, Next.js, TailwindCSS and Prisma. Mixing this with Next.js api/ routes is amazing. Let us take a look.


Next.js

First of, we'll install Next.js, run:

npx create-next-app nextjs-and-prisma

Once installed, let us take care of Prisma, navigate to the project's folder and run:

npm install prisma --save-dev

By installing Prisma, it comes with a CLI, we can use it to init our Prisma instance:

npx prisma init

This will create 2 files: prisma/schema.prisma and .env.

If you open .env you'll notice there's already a DATABASE_URL example there, if you're using Postgres just change the username, password and database name to match your configuration, otherwise you can either use SQLite with Prisma or you can setup Postgres on your machine.

For this tutorial we're going with SQLite, open .env and update DATABASE_URL:

DATABASE_URL=file:./dev.db

Schema

Open prisma/schema.prisma, you should see something like:

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

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

Let us change our provider and create or first model:

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

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

model User {
  id      Int      @id @default(autoincrement())
  email   String   @unique
  name    String?
}

Awesome, now on the terminal run npx prisma db push, this will push our model to the database and generate the prisma client for us.


API

Now we'll create a new Next.js API route, run:

touch pages/api/users.js

Inside that file put:

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export default async function handler(req, res) {
  const users = await prisma.user.findMany()

  res.status(200).json(users)
}

It's that easy, this API route will return all users, we still don't have any though, we'll take care of that now.


Relations

Creating relations between models with Prisma is really easy, let us update our schema:

model User {
  id      Int      @id @default(autoincrement())
  email   String   @unique
  name    String?

  account   Account? @relation(fields: [accountId], references: [id])
  accountId Int?
}

model Account {
  id      Int      @id @default(autoincrement())
  name    String
  user    User?
}

It's that easy, push it to the database — npx prisma db push.


Seed the database

Create a seed.js file inside the prisma folder and put this inside it:

const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()

const users = [
  { name: 'Elon Musk', email: 'elon@tesla.com' },
  { name: 'Jeff Bezos', email: 'jeff@amazon.com' },
]

async function main() {
  await prisma.$transaction(
    users.map(({ name, email }) => {
      return prisma.user.create({
        data: {
          name,
          email,
          // It's this easy to either `create` or `connect`
          // accounts when creating a `user`.
          account: {
            create: {
              name: `${name} account`,
            },
          }
        },
      })
    }),
  )
}

main()
  .catch((e) => {
    console.error(e)
    process.exit(1)
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

To be able to seed our database we still need to add these lines inside our package.json file:

"prisma": {
  "seed": "node prisma/seed.js"
}

We should be good to go, try running npx prisma db seed.


In case you run to any errors make sure to restart your application.


Call it

Great, if you open your browser and check http://localhost:3000/api/users you should see that's now returning the two users we seeded.

Although, we might want to also include the account of the users as well, go to api/users.js and update it:

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export default async function handler(req, res) {
  const users = await prisma.user.findMany({
    include: { account: true },
  })

  res.status(200).json(users)
}

Boom!


That's a wrap, hope this can be useful in some way.

Read next
The Tale: Learning Javascript in 2 days
June 14, 2021
views