Alvin Chang

Connecting Prisma to a Next.js App for Full-Stack Development

October 14, 2024

Prisma is an open-source ORM (Object-Relational Mapping) tool that helps developers interact with their databases in a more intuitive and efficient way. It works seamlessly with Next.js to create full-stack applications, allowing you to manage your database directly within your Next.js app. In this guide, we’ll demonstrate how to set up and use Prisma with Next.js to build a full-stack application with ease.


1. Setting Up Your Next.js Project

First, let’s create a new Next.js application if you don’t already have one set up:

npx create-next-app@latest my-prisma-app
cd my-prisma-app

Install the necessary dependencies:

npm install @prisma/client
npm install -D prisma

The @prisma/client package is the runtime that you’ll use to interact with your database, while prisma is the CLI used to manage your Prisma setup.

2. Initializing Prisma

Next, initialize Prisma in your project:

npx prisma init

This command creates a prisma directory in your project root, containing a schema.prisma file. This file defines your database schema and acts as the single source of truth for your database structure.

3. Setting Up the Database

To connect Prisma to your database, open the .env file that was generated in your project’s root. Update the DATABASE_URL with your database connection string. For this example, let’s assume you’re using a local SQLite database:

DATABASE_URL="file:./dev.db"

This configuration sets up an SQLite database located at dev.db in your project directory. You can use other databases like PostgreSQL or MySQL by providing the appropriate connection string.

4. Defining the Schema

Open the schema.prisma file and define your first model. For this example, we’ll create a simple Post model:

// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

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

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String
  published Boolean  @default(false)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

This schema defines a Post model with fields for the ID, title, content, published status, and timestamps. Prisma uses this schema to generate the database structure and code that interacts with it.

5. Migrating the Database

To create the database tables based on your schema, you need to run a migration. Execute the following command:

npx prisma migrate dev --name init

This command:

  • Creates the dev.db SQLite database (if it doesn’t already exist).
  • Applies the schema changes and creates a migration file that documents the changes.
  • Updates your database schema based on the schema.prisma file.

6. Generating Prisma Client

Prisma’s client generation feature allows you to use TypeScript-typed functions to query your database. To generate the client:

npx prisma generate

Now, you can use Prisma’s client directly within your Next.js application to interact with your database.

7. Using Prisma in Your Next.js API Routes

Next.js allows you to create API routes inside the pages/api directory. Let’s create a new API route to retrieve all posts from the database.

Create a new file at pages/api/posts.js:

// pages/api/posts.js
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  if (req.method === 'GET') {
    try {
      const posts = await prisma.post.findMany();
      res.status(200).json(posts);
    } catch (error) {
      res.status(500).json({ error: 'Failed to fetch posts' });
    }
  } else {
    res.status(405).json({ error: 'Method not allowed' });
  }
}

In this code:

  • We import PrismaClient and create an instance of it.
  • We handle a GET request to retrieve all posts from the Post table using prisma.post.findMany().
  • The response returns the posts as JSON.

8. Creating a New Post API Route

Let’s also create an API route to add new posts. Create another file at pages/api/createPost.js:

// pages/api/createPost.js
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { title, content } = req.body;
    try {
      const newPost = await prisma.post.create({
        data: {
          title,
          content,
          published: false,
        },
      });
      res.status(201).json(newPost);
    } catch (error) {
      res.status(500).json({ error: 'Error creating post' });
    }
  } else {
    res.status(405).json({ error: 'Method not allowed' });
  }
}

This route handles POST requests:

  • It reads the title and content from the request body.
  • It creates a new post using prisma.post.create().
  • It responds with the newly created post as JSON.

9. Setting Up a Simple Frontend

Now that the backend is set up, let’s create a simple frontend to display the posts. Modify your pages/index.js:

// pages/index.js
import { useState, useEffect } from 'react';

export default function Home() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    async function fetchPosts() {
      const response = await fetch('/api/posts');
      const data = await response.json();
      setPosts(data);
    }
    fetchPosts();
  }, []);

  return (
    <div className="container">
      <h1>All Posts</h1>
      {posts.map((post) => (
        <div key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  );
}

This code fetches posts from the /api/posts route and displays them on the page. It uses the useEffect hook to fetch data when the component loads and sets the posts state with the data.

10. Deploying Your Next.js App

To deploy your Next.js app with Prisma, you can use platforms like Vercel or Netlify. Both support serverless functions, which is perfect for your API routes. Ensure that your environment variables (e.g., DATABASE_URL) are correctly configured in your deployment settings.

If you’re using Vercel:

  1. Deploy the project via the Vercel CLI or through Git integration.
  2. Set the environment variables in the Vercel dashboard.
  3. Once deployed, the serverless functions will handle your API requests and connect to your Prisma database as expected.

Conclusion

By integrating Prisma with Next.js, you create a full-stack application that efficiently manages both the frontend and backend. Prisma’s powerful ORM features, combined with Next.js’s serverless API capabilities, enable you to build robust and scalable applications with minimal setup.

Whether you’re building a blog, an e-commerce platform, or a complex web app, this combination of tools makes development faster, cleaner, and more maintainable. Start experimenting with Prisma in your Next.js projects today and unlock the full potential of full-stack development!

Made with ❤️ by Aurora

© 2024 Alvin Chang | Full-Stack Developer. All rights reserved.