CreateLife ~AlwaysLatest~

【Next.js】Supabaseを使ってデータのやり取りを実装する

Next.js

本業ではバックエンドをメインに扱っているのでNext.jsを学んでいると「データベースはどうしたらいいの」がなかなか難しい。(選択肢が多いし、何が良いのかよくわからない)今回はsupabaseというBaaS(Backend as a Serviceの略でサーバー側のバックエンド機能を提供するクラウドサービスのこと)を使ってデータベースを構築してみる。

目次

  1. supabaseでプロジェクトを作成
  2. .envファイルを作成
  3. prismaをインストールしてプロジェクトと連携
  4. モデルを作成してテーブルを作る
  5. prisma@clientを使ってテーブルからデータを取得する
  6. まとめ

1. supabaseでプロジェクトを作成

supabaseにサインイン

公式はこちら

プロジェクト作成

パスワードは後ほど使うのでメモっておく。
リージョンは日本に

projectAPIのURLとAPIKeyをメモ

2. .envファイルを作成

ドキュメントに従ってプロジェクトのルートディレクトリに.envファイル(.env.local)を作成し、先ほど取得した値を使って下記のように記述

  NEXT_PUBLIC_SUPABASE_URL=<SUBSTITUTE_SUPABASE_URL>
  NEXT_PUBLIC_SUPABASE_ANON_KEY=<SUBSTITUTE_SUPABASE_ANON_KEY>

3. prismaをインストールしてプロジェクトと連携

そもそもprismaとは、、

オープンソースのORM(Object-relational mapping)
Node上のアプリケーションで直接DBに接続し、クエリー発行が可能
RDB周りの処理をより簡単に行えるようにし、開発者の生産性を向上させることを目的に開発
Next.jsアプリケーションでDBを扱う際に特に有用
Schemaファイルから型情報が生成され、クエリ結果がタイプセーフになる

とのこと。(引用元)簡単にいうとSQLを知らなくてもデータベースを扱えるよ!というもの、だと思う。

prismaをインストール

詳細は公式サイトにあるが、下記にて実行

npm install prisma --save-dev

すると、prisma/schema.prismaというファイルが出来上がり、先ほど作成した.envにDATABASE_URLの値が追加されている。prisma/schema.prismaにてenv(‘DATABASE_URL’)の値が読み込まれている。(値は要調整)

作成したプロジェクトのConnectURIを先ほどのDATABASE_URLに置き換える

4. モデルを作成してテーブルを作る

prisma/schema.prismaを編集

記事テーブルだけ作ってみる

generator client {
provider = “prisma-client-js”
}

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

# ↓これを追加
model Post {
id Int @id @default(autoincrement())
username String
title String
content String
createdAt DateTime @default(now())
}

マイグレーションを実行

マイグレーションとは、Prisma(ORM)に記載した情報をもとにDBのスキーマを書き換えること

npx prisma migrate dev --name init

prisma/migrationsディレクトリが作成され、ファイルが作成されている

追加されたPostテーブルにデータを適当に入れておく

supabaseのTableEditorを覗くとPostテーブルが追加されているのでInsertボタンからいくつかデータを挿入しておく

5. prisma@clientを使ってテーブルからデータを取得する

prisma@clientをインストール

npm install @prisma/client

ベストプラクティスに基づいてファイルを作成

インストールしたprismaクライアントをそのままページファイルでimportして使いたいところですが、開発中のホットリロード機能によって毎回prismaクライアントがインスタンス化されるのが良くないらしい。公式にベストプラクティスの記述があるのでそれに基づいてlibディレクトリを作成し、その配下にprismaClient.tsというファイルを作成し、以下の内容を記述

import { PrismaClient } from '@prisma/client'

const prismaClientSingleton = () => {
  return new PrismaClient()
}

declare global {
  var prismaGlobal: undefined | ReturnType<typeof prismaClientSingleton>
}

const prisma = globalThis.prismaGlobal ?? prismaClientSingleton()

export default prisma

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

この記述によって開発環境では1度インスタンス化したprismaクライアントを保存し、それを使用するということができる。

データを取得する

データ取得のためのAPIを用意する

公式サイトに基づいてapp/api/post/route.tsファイルを作成し、ここで先ほどのprismaクライアントをimportし、GETメソッドを追加する

import prisma from "@/lib/prismaClient";
import { NextResponse } from "next/server";

export async function GET(req: Request) {
    const allBBSPosts = await prisma.post.findMany();
    return NextResponse.json(allBBSPosts);
}

このように記述することで、http://localhost:3000/api/postというURLで上記のファイルを実行できるようになる。

fetchしてみる

app/page.tsxにて下記のように記述して保存する

export default async function Home() {
  const response = await fetch("http://localhost:3000/api/post", {
    cache: "no-store",
  });

  const result = await response.json();
  console.log(result);

  return (
    <main>

    </main>
  );
}

取得を確認!

6. まとめ

supabaseで作成したデータベースからORM(prisma)を使用してデータを取得することができました。
サーバーを立てて、MySQLをインストールして、、のような従来のやり方と比べるとかなり簡単でした。
しかも無料(2024年4月現在)。まだまだsupabaseの認証機能や、その他便利なものが用意されているようなので色々試してみようと思います。