Next.js13、Prisma、Supabase備忘録

Next.js、Prisma、Supabaseを簡単に使用してフルスタックの開発を体験してみたので、その備忘録として自分が大事だなと思ったことを記述しておきたいと思います。

開発初心者が今後の学習にも活かすため、記事を書いております。どうか暖かい目でお願いします（笑）。

## 手順
「Next.jsの準備」、「Supabaseの準備」、「Prismaの準備」、「REST API作成」、「Next.js 記述」という手順で進めました。

## Next.jsの準備
```
$ npx create-next-app@latest
```
プロジェクト名をつけ、「import alias」 以外をYesで作成します。

## Supabaseの準備
#### Supabaseアカウント登録
私は初めて使ったので登録からでした。
githubアカウントで簡単に登録ができます。

https://supabase.com/
#### 新規プロジェクトの作成
アカウントが登録できたら左の「Dashboard」にある「All projects」を選択します。
ここに既に作成したプロジェクトがあれば表示されることになります。

緑色の「New project」というボタンを押し、自身のアカウントを選択すると次の画像のような状態になると思います。

![スクリーンショット 2023-11-19 14.57.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852831/001ce9fb-191f-9ff2-ea99-31f80f294fcd.png)

ここでは既に入力してありますが、ご自身で「Name」、「Database Password」、「Region」を決めてください。

::: note info
「Database Password」は後で使用しますので、保存しておいてください。
:::

右下の緑色の「Create new project」というボタンを押すと、新規プロジェクトの作成に成功し、自身の作成したプロジェクトのページに飛びます。

#### Database URLの取得
![スクリーンショット 2023-11-19 15.31.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852831/b8894b8b-cace-9eec-fd1f-aa10e92fec7a.png)

歯車マークの「設定」->「Database」を押すと画像のような画面が表示されます。
「Connection string」の「URI」という部分が後々必要になるのでコピーしておきましょう。



## Prismaの準備
#### prisma install & prisma init
Prismaを開発環境に保存し、セットアップします。

```
$ npm install prisma --save-dev
$ npx prisma init
```

https://www.prisma.io/docs/getting-started/quickstart

そうすると開発環境に「prisma」フォルダが作成され、中に「schema.prisma」ファイルと別で「.env」ファイルが作成されていると思います。

```js: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
  description String
  date        DateTime @default(now())
}
```


```php:.env
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL="postgres://postgres.senhwmcethfnfhegewtx:[YOUR-PASSWORD]@aws-0-ap-northeast-1.pooler.supabase.com:6543/postgres"
```
「.env」ファイルのDATABASR_URLに先程Supabaseの準備の際にコピーしたURLを貼り付けます。
そして、[YOUR-PASSWORD]をプロジェクト作成時に設定した「Database Password」に変えます。

#### prisma migrate
データベースのスキーマを変更する際、prisma migrateを使用してマイグレーションファイルを生成します。マイグレーションファイルにはスキーマ変更の手順が含まれ、これによりデータベースを新しいスキーマにアップデートできます。
```
$ npx prisma migrate dev
```

すると「prisma」フォルダ内に「migrations」というフォルダができていると思います。
中を見ていると次のようなSQLが生成されています。
とても簡単に作成することができました。

```sql:migration.sql
-- CreateTable
CREATE TABLE "Post" (
    "id" SERIAL NOT NULL,
    "title" TEXT NOT NULL,
    "description" TEXT NOT NULL,
    "date" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT "Post_pkey" PRIMARY KEY ("id")
);
```

https://www.prisma.io/docs/concepts/components/prisma-migrate/migrate-development-production#create-and-apply-migrations

## REST APIの作成
Next.js13だと「src」->「app」を選択した状態で、「api」フォルダを作成し、「blog」フォルダを作成し、さらにその中に「route.ts」ファイルを作成するようです。（多分「blog」フォルダはエンドポイント用なので名称自由。）

ディレクトリで管理できるのは便利ですが、勉強不足で知らないと詰みますね...。
今回の件でNext.js13について、もう少し資料を読んでの情報収集が必要だと感じました。

データの全取得や追加であれば、このファイル内で記載していきます。

```ts:blog / route.ts
import { PrismaClient } from "@prisma/client";
import { NextResponse } from "next/server";

const prisma = new PrismaClient();

export async function main() {
	try {
		await prisma.$connect();
	} catch (err) {
		return Error("Fail DB connect");
	}
}

// 取得
export const GET = async (req: Request, res: NextResponse) => {
	try {
		await main();
		const posts = await prisma.post.findMany();
		return NextResponse.json({ message: "Success", posts }, { status: 200 });
	} catch (err) {
		return NextResponse.json({ message: "Error", err }, { status: 500 });
	} finally {
		await prisma.$disconnect();
	}
};
```

比較的処理の内容に関してはわかりやすく驚きました。お手軽ですね。


次にデータを1つずつ取得、書き換える用に「api」->「blog」を選択した状態で、「[id]」フォルダを作成し、その中に「route.ts」を作成して記述すれば良いようです。

## Next.js 記述
最後にですが、APIをpage.tsxで叩いて行こうと思います。
とりあえず表示できるところ目指します。

```tsx:page.tsx
import { PostType } from "@/types";
async function fetchBlogs() {
    // エンドポイントを指定
    // 今回はvercelなどにあげないのでローカル
	const res = await fetch("http://localhost:3000/api/blog", {
		// 更新が頻繁に行われるのでSSR
		// SSGなら "force-cache"
		cache: "no-store",
	});

	const data = await res.json();
	return data.posts;
}

export default async function Home() {
	const posts = await fetchBlogs();
    return (
        <>
            {posts.map((post: PostType) => (
                <div key={post.id}>
                    <div>{post.title}</div>
                    <div>{post.description}</div>
                    {/* Date型が割り当てられないためstring型にする */}
                    <div>{new Date(post.date).toDateString()}</div>
                </div>
            ))}
        </>
    );
 }
 ```
 今回はとりあえず表示だけしておりますが、編集や削除もボタンを作成してそこでイベントを起こせばお手軽に実装できそうです。
 ちなみにPostTypeはこんな感じです。
 ```ts: type.ts
 export type PostType = {
	id: number;
	title: string;
	description: string;
	date: Date;
};
```

## まとめ
かなり簡単にフルスタック開発の準備や基礎が整ったことが魅力的でしたが、Next.js13に関して、勉強不足でした。今まで詰まっていたAPIの作成がディレクトリ管理で、知っていればあんなに簡単に実装できるとは...。

今後、自身の活動を投稿するブログアプリや就活に関する予定をチャットbotで簡単に管理するアプリを作ってみたいと考えていますが、今回の技術スタックで挑戦したいと思いました。