【新機能】Vercel Postgres + Next.js + PrismaでフルスタックWebアプリケーションを作ってみた
はじめに
GWに入り、5日連続のVercelによる新機能の発表が始まりました。早速初日(2023 5/1)からすさまじい機能の発表がありました。
初日に発表されたのは、以下の三つのStorageサービスです。
- Vercel Postgres
- Vercel KV
- Vercel Blob
今回はこの中のVercel Postgresを実際に使いながら、ClientからServerまで網羅しためっちゃ簡易的なフルスタックなアプリケーションを、実用性の側面も加味してPrisma + Next.jsで作っていこうと思います。
Vercel CLIの導入
Vercel Postgresのセットアップにあたって、ぶっちゃけなくても開発できますが、Vercel CLIは非常に便利なので導入しましょう。
yarn global add vercel
export PATH=$PATH:~/.yarn/bin
↑↑↑ターミナル開くごとに毎回export PATH...はだるいので、zshrc
などに記載することをお勧めします。
vercel -v
# => Vercel CLI 29.0.3
Vercel Postgresのセットアップ
まず、Vercelのダッシュボードのヘッダーのstorageから進めていきます。
次に、Create Databaseから実際にデータベースを作成していきます。
Create Databaseをクリックすると、下記のスクショのようなStorageサービスを選択を行います。
最後にデータベース名とリージョンを決定して無事完成です。
Vercel Postgresをプロジェクトに紐付ける
ダッシュボード上でプロジェクトとVercel Postgresの接続を行います。
Vercelのプロジェクトが存在しない場合は、Vercel link
コマンドでプロジェクトの作成から行えます。
ここでデータベースのcredential情報が取得できたので、次にローカルに環境変数をプルします。
環境変数をローカルにプルする
下記のコマンドで、先ほど作成したデータベースのcredentail情報をローカルにプルしてきます。
vercel env pull .env
このコマンドを実行すると、ローカルのプロジェクトに.envファイルが作成されます。また以下のようにいくつかの環境変数が記述されています。
# Created by Vercel CLI
VERCEL="1"
VERCEL_ENV="development"
TURBO_REMOTE_ONLY="true"
NX_DAEMON="false"
VERCEL_URL=""
VERCEL_GIT_PROVIDER=""
VERCEL_GIT_PREVIOUS_SHA=""
VERCEL_GIT_REPO_SLUG=""
VERCEL_GIT_REPO_OWNER=""
VERCEL_GIT_REPO_ID=""
VERCEL_GIT_COMMIT_REF=""
VERCEL_GIT_COMMIT_SHA=""
VERCEL_GIT_COMMIT_MESSAGE=""
VERCEL_GIT_COMMIT_AUTHOR_LOGIN=""
VERCEL_GIT_COMMIT_AUTHOR_NAME=""
VERCEL_GIT_PULL_REQUEST_ID=""
POSTGRES_URL="postgres:~~~~"
POSTGRES_URL_NON_POOLING="postgres:~~~~"
POSTGRES_PRISMA_URL="postgres:~~~~"
POSTGRES_USER="~~~~"
POSTGRES_HOST="~~~~"
POSTGRES_PASSWORD="~~~~"
POSTGRES_DATABASE="~~~~"
Prismaをセットアップ
まずは、必要なパッケージをインストールします。
yarn add @vercel/postgres
yarn add prisma @prisma/client
次にSchema.prismaでmigrationを定義します。
generator client {
provider = "prisma-client-js"
previewFeatures = ["jsonProtocol"]
}
datasource db {
provider = "postgresql"
url = env("POSTGRES_PRISMA_URL")
directUrl = env("POSTGRES_URL_NON_POOLING")
shadowDatabaseUrl = env("POSTGRES_URL_NON_POOLING")
model Post {
id Int @id @default(autoincrement())
title String
description String
}
最後にmigrationを実行したらPrismaのセットアップ完了です。
npx prisma generate
以上で、PrismaおよびVercel Postgresのセットアップが完了したので、ここからPostのCRUDなAPIを実装していきます。
※ 個人的な好みですがAPI clientの初期化をlibでやっております。
import { PrismaClient } from "@prisma/client";
export const prisma = new PrismaClient();
API RouteでのAPI実装
基本機能ということで、今回はGet
とCreate
とDelete
をAPI Routeで実装いたしました。
各APIは以下のようになっています。
APIとして完全な要件を満たせているわけではありませんが、よかったら参考にしてみてください。
import { NextApiRequest, NextApiResponse } from "next";
import { prisma } from "@/lib/prisma";
export default async function handler(
_request: NextApiRequest,
response: NextApiResponse
) {
try {
const data = await prisma.post.findMany();
return response.status(200).json({ data });
} catch (error) {
return response.status(500).json({ error });
}
}
import { NextApiRequest, NextApiResponse } from "next";
import { prisma } from "@/lib/prisma";
export default async function handler(
request: NextApiRequest,
response: NextApiResponse
) {
const { title, description } = JSON.parse(request.body);
try {
const data = await prisma.post.create({
select: {
id: true,
title: true,
description: true,
},
data: {
title: title,
description: description,
},
});
return response.status(200).json({ data });
} catch (error) {
return response.status(500).json({ error });
}
}
import { NextApiRequest, NextApiResponse } from "next";
import { prisma } from "@/lib/prisma";
export default async function handler(
request: NextApiRequest,
response: NextApiResponse
) {
const { id } = JSON.parse(request.body);
try {
const data = await prisma.post.delete({
where: {
id: parseInt(id, 10),
},
});
return response.status(200).json({ data });
} catch (error) {
return response.status(500).json({ error });
}
}
※フロントエンドのソースコード等については、本筋から外れてしまうため割愛いたします。
詳しいソースコードについては以下をご参照ください。
Vercelにデプロイする
ここから実際にアプリケーションをデプロイしていきます。
基本的には普段通りのVercelデプロイと何ら変わりはありませんが、今回はORMとしてPrismaを採用しているため、ビルド時にprisma generateを実行する必要があります。
...
"scripts": {
"dev": "next dev",
"build": "prisma generate && prisma db push && next build",
"start": "next start",
"lint": "next lint"
},
...
あとは必要なソースコードをmainにマージすればデプロイが走ります。
まとめ
最後までご覧いただきありがとうございます。
Vercel + Next.jsでバックエンドからフロントエンド、さらにはデプロイまで完結するため、これはもはやWebアプリケーション開発の完成形と言っても過言ではありませんね。
特に、TanStack Query(旧React Query)との相性は抜群かなと思います。
これでもう小規模な開発であれば別でAPIサーバを建てるのも不要になるかもしれないですね。😅
またVercelの残りの発表も気になるところではありますので、楽しみにしたいと思います!!!
参考情報
Discussion
Schema.prismaに閉じカッコが1つ足りていないようです