👷‍♂️

Next.js + Prisma + Supabase でプロジェクト立ち上げ

2022/01/07に公開

Webアプリのプロト環境をサクッと立ち上げたい

主に趣味の開発でサクッと動くものを立ち上げて、少しずつ手を入れながら PoC 的にプロダクトのイメージを固めていきたいというような場面がしばしばあります。そのようなときに使えそうな構成として、 Next.js + Prisma + Supabase でのプロジェクト立ち上げを試してみたのでメモを残しておこうと思います。

初期設定

Next.js プロジェクトを作成し、 Prisma をインストール・初期化します。

$ npx create-next-app@latest --typescript
$ cd <project dir>
$ yarn add --dev prisma
$ npx prisma init

Prisma のスキーマファイル prisma/schema.prisma.env が作成されます。

Supabaseのプロジェクトを作成

SupabaseにGithubアカウントでログインし、プロジェクトを作成します。プロジェクトの名前とDBパスワードを入力し、デフォルトで Pro tier になっている Pricing Plan を Free tier に変更して Create new project ボタンをクリックします。

自分はなぜか最初にログインしたときに You do not have permission to create a project という警告が出てプロジェクトを作成できませんでしたが、ページを再読み込みしたら直りました。

DBマイグレーション

今回はテストなのでPrismaの公式ドキュメントのサンプルのスキーマをそのままスキーマファイルに貼り付けます。

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

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

// 以下貼り付け箇所

model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  title     String   @db.VarChar(255)
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
}

model Profile {
  id     Int     @id @default(autoincrement())
  bio    String?
  user   User    @relation(fields: [userId], references: [id])
  userId Int     @unique
}

model User {
  id      Int      @id @default(autoincrement())
  email   String   @unique
  name    String?
  posts   Post[]
  profile Profile?
}

次に Supabase のダッシュボードの該当プロジェクトの Settings > Database 内の Connection String をコピーし、 .envDATABASE_URL の値として貼り付けます。

.env
DATABASE_URL=<Connection String>

最後に Prisma のマイグレーションコマンドを実行します。

$ npx prisma migrate dev --name init

このとき prisma generate コマンドが走るようで、 @prisma/client が自動的に依存に追加されました。またマイグレーション関連のファイル群が prisma/migrations ディレクトリに追加されました。

Supabase のダッシュボードの Database > Tables をみると、スキーマ通りにテーブルが作成されていることが確認できます。

getServerSidePropsでデータ取得、ログ出力

こちらの記事を参考に、 getServerSideProps で Prisma Client を利用してデータを取得してみます。

lib/prisma.ts
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient({
  log: ["query", "error", "info", "warn"],
});
export default prisma;

export * from "@prisma/client";

pages/index.tsx
import type { GetServerSideProps, NextPage } from 'next'
import prisma from '../lib/prisma'
import styles from '../styles/Home.module.css'

interface Props {
  count: number
}

export const getServerSideProps: GetServerSideProps<Props> = async () => {
  const count = await prisma.user.count()
  return {
    props: {
      count
    }
  }
}

const Home: NextPage<Props> = ({ count }) => {
  return (
    <div className={styles.container}>
      <h1>{`User Count: ${count}`}</h1>
    </div>
  )
}

export default Home

下のように画面が表示されます。

またサーバのコンソールには Prisma が実行したクエリのログが出ます。

prisma:query SELECT COUNT(*) FROM (SELECT "public"."User"."id" FROM "public"."User" WHERE 1=1 OFFSET $1) AS "sub"

良さそう

立ち上げはかなり簡単でした。この構成である程度動くものを作ってみようと思います。

参考

https://zenn.dev/mizchi/articles/1c35fdcc77065c02f631#next.js-から-prisma-を利用する
https://dev.to/prisma/set-up-a-free-postgresql-database-on-supabase-to-use-with-prisma-3pk6
https://vercel.com/guides/nextjs-prisma-postgres

Discussion