Prisma & Next.js

Learn how to use Prisma with a Next.js application to persist data to a PostgreSQL database. I'll also show you how to setup a cloud database using railway and deploy your app to vercel.

Complete Code: https://github.com/Sam-Meech-Ward/code_snippets_prisma_next_demo.git

Links about Env Vars: https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices https://nextjs.org/docs/basic-features/environment-variables

Chapters:

  • 0:00​ Intro
  • 2:44 Installing Prisma
  • 3:35 Environment Variables
  • 6:37 Connect to local Postgres
  • 7:44 Setup schema/models
  • 9:28 Run migration
  • 10:25 Prisma Studio
  • 11:32 Posting data
  • 20:01 Create a single prisma client
  • 22:36 Getting data
  • 26:45 Serializable Data
  • 30:28 Deploy to the cloud
  • 37:20 Summary

Code

schema.prisma

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

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

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

model Post {
  id            Int      @id @default(autoincrement())
  title         String
  code          String   @db.Text
  language      String
  totalLikes    Int      @default(0)
  totalComments Int      @default(0)
  createdAt     DateTime @default(now())
  updatedAt     DateTime @updatedAt
}

server/db/client.js

import { PrismaClient } from '@prisma/client'

export const prisma =
  global.prisma ||
  new PrismaClient()

if (process.env.NODE_ENV !== 'production') global.prisma = prisma

pages/api/posts.js

import { prisma } from '../../server/db/client'

function titleFromCode(code) {
  return code.trim().split('\n')[0].replace('// ', '')
}

export default async function handler(req, res) {
  const { method } = req

  switch (method) {
    case 'POST':
      const {language, code} = req.body
      const title = titleFromCode(code)
      const post = await prisma.post.create({
        data: {
          title,
          language,
          code,
        },
      })
      res.status(201).json(post)
      break
    default:
      res.setHeader('Allow', ['POST'])
      res.status(405).end(`Method ${method} Not Allowed`)
  }
}

pages/index.js

import { prisma } from '../server/db/client'

import PostSmall from '../components/PostSmall'
import Button from '../components/Button'

export default function Home({ posts }) {
  return (
    <>
      <div className="pt-8 pb-10 lg:pt-12 lg:pb-14 mx-auto max-w-7xl px-2">

        <div className='max-w-2xl mx-auto'>

          <ul className='mt-8'>
            {posts?.map(post => (
              <li key={post.id}>
                <PostSmall
                  post={post}
                />
              </li>
            ))}
          </ul>

        </div>
      </div>
    </>
  )
}

export async function getServerSideProps() {
  // will always run on the server
  // newest first
  const posts = await prisma.post.findMany({
    orderBy: {
      createdAt: 'desc'
    }
  })

  return {
    props: {
      posts: JSON.parse(JSON.stringify(posts)),
    },
  }
}

Find an issue with this page? Fix it on GitHub