Hono + Prisma + Cloudflare D1/R2をローカルだけで動かしてみる
概要
タイトル通りですが、Hono + Prisma + CloudflareのD1/R2のローカル環境をセットアップして、デプロイはせずにローカルだけで動かしてみて、挙動の確認などを試してみたいと思います。
👇以下軽く各サービスの概要説明になります。
Hono とは
Edgesのための小さくシンプルで超高速なWebフレームワークです。どのJavaScriptランタイムでも動作します:Cloudflare Workers、Fastly Compute、Deno、Bun、Vercel、Netlify、AWS Lambda、Lambda@Edge、Node.js
Prisma とは
Prismaは、Node.jsとTypeScriptのための次世代のORM (Object-Relational Mapping) です。データベースとのやり取りをより簡単かつ安全にするために設計されています。開発者がデータベーススキーマを定義し、そのスキーマに基づいて自動的に型安全なクライアントAPIを生成します。これにより、SQLやデータベース固有のクエリ言語に依存することなく、データベースとのやり取りが可能になります。
Cloudflare D1 とは
Cloudflare D1は、Cloudflareが提供する分散型SQLデータベースサービスです。D1は、データベースのパフォーマンスとスケーラビリティを向上させ、グローバルに分散されたデータベースを簡単に構築・管理できます。サーバーレスアーキテクチャに基づいており、高速なクエリ応答と高い可用性を実現します。これにより、開発者は複雑なインフラ管理を不要にし、アプリケーションの迅速な開発とデプロイを可能にします。
Cloudflare R2 とは
Cloudflare R2は、データ転送費用をなくしたオブジェクトストレージサービスです。Amazon S3と互換性があり、移行が容易です。大規模なデータ保存を低コストで提供し、既存のS3ツールやアプリともシームレスに統合できます。
環境構築
今回も👇の環境をcloneして構築していきます。(※ nodeが動く環境なら好きな環境で試してもらえればと思います)
次に👇のファイルを少し修正してます。
.devcontainer/Dockerfile
FROM node:20.10.0-bullseye-slim
LABEL maintainer="Slowhand0309"
ARG username=vscode
ARG useruid=1000
ARG usergid=${useruid}
RUN set -ex \
&& apt-get update \
&& apt-get install -y \
sudo \
ca-certificates \ # ← 追加
--no-install-recommends \
# Delete node user with uid=1000 and create vscode user with uid=1000
&& userdel -r node \
&& groupadd --gid ${usergid} ${username} \
&& useradd -s /bin/bash --uid ${useruid} --gid ${usergid} -m ${username} \
&& echo ${username} ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/${username} \
&& chmod 0440 /etc/sudoers.d/${username}
USER ${username}
.devcontainer/compose.yaml
services:
app:
...
ports:
- "8787:8787" # ← 追加
ここまできたらコンテナ起動し、コンテナ内で👇コマンドからhono + Cloudflare workers の環境をセットアップしていきます。
$ yarn create hono .
✔ Using target directory … .
? Which template do you want to use? cloudflare-workers
? Directory not empty. Continue? yes
✔ Cloning the template
? Do you want to install project dependencies? yes
? Which package manager do you want to use? yarn
✔ Installing project dependencies
🎉 Copied project files
wrangler.toml
に👇を追加し、
[dev]
ip = "0.0.0.0"
port = 8787
コンテナ再起動して yarn dev
で http://localhost:8787/ にアクセスし、「Hello Hono!」が表示されていればOKです。
完全ローカルだけの D1 環境構築
wrangler.toml
に👇を追加します。
[[d1_databases]]
binding = "DB"
database_name = "trial-d1"
database_id = "1"
この時ローカルのみの環境なので database_id
は空出なければ何でもいいみたいです。
試しにseedデータ登録
次に試しに👇の seed.sql
を作成しときます。
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL);
INSERT INTO users VALUES (1,'山田 太郎');
INSERT INTO users VALUES (2,'鈴木 花子');
次にこれをローカルのD1環境に対して実行してみます。
yarn wrangler d1 execute trial-d1 --local --file=seed.sql
👆を実行すると自分の環境では .wrangler/state/v3/d1/miniflare-D1DatabaseObject/XXXX.sqlite
が作成され、SQLクライアントツールで開くとちゃんと users
テーブルが作成され、データが登録されていました ✨
確認できたらこの後マイグレーションで別途テーブル作成するので、.wrangler/state/v3/d1/miniflare-D1DatabaseObject/XXXX.sqlite
を削除しときます。
Prisma環境構築
先ずは必要なパッケージをインストールしていきます。
yarn add -D prisma
yarn add @prisma/client @prisma/adapter-d1
次にPrismaを初期化します。
npx prisma init --datasource-provider sqlite
次に生成された prisma/schema.prisma
に👇を追加します。
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"] # ← 追加
}
最後に wrangler.toml
にCloudflare WorkersでNode.jsのAPIを有効化するため👇を追加します。
name = "...."
compatibility_date = "2024-07-24"
compatibility_flags = ["nodejs_compat"]
マイグレーション
改めて users
テーブルを作成すべく、先にマイグレーションファイルを作成しときます。
yarn wrangler d1 migrations create trial-d1 users
👆を実行すると手元の環境だと migrations/0001_users.sql
が作成されました。
次に prisma/schema.prisma
に users
テーブルを設定します。
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
最後にPrismaのmigrateコマンドを実行します。
yarn prisma migrate diff --from-empty --to-schema-datamodel ./prisma/schema.prisma --script --output migrations/0001_users.sql
すると空だった migrations/0001_users.sql
は👇の様に更新されました。
-- CreateTable
CREATE TABLE "User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"email" TEXT NOT NULL,
"name" TEXT
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
ローカルのD1へ👆のマイグレートを反映させてみます。
yarn wrangler d1 migrations apply trial-d1 --local
sqlファイルを開いてみるとちゃんと反映されています。
ちなみに、次回以降のマイグレーションはどうするのかというと、 yarn prisma migrate diff
で --from-empty
の部分を --from-local-d1
としてやることでローカルのD1を見にいき prisma/schema.prisma
との差分を取ってくれます。
完全ローカルだけの R2 環境構築
wrangler.toml
に👇を追加します。
[[r2_buckets]]
binding = "R2"
bucket_name = "trial-r2"
お試し用の seed.json
を👇内容で作成します。
{
"users": [
{
"name": "John Doe",
"email": "john@example.com"
}
]
}
次にこれをローカルのR2環境へputしてみます。
yarn wrangler r2 object put trial-r2/users --local --file=seed.json
実行すると自分の環境では .wrangler/state/v3/r2/my-bucket/blobs/xxxxx...
が作成されていました。
objectが反映されているか /storage
にアクセスするとobject一覧の情報が返るようなAPIを作成して確認してみたいと思います。
src/index.ts
を👇内容に変更します。
import { Hono } from 'hono';
type Bindings = {
DB: D1Database;
R2: R2Bucket;
};
const app = new Hono<{ Bindings: Bindings }>();
app.get('/', (c) => {
return c.text('Hello Hono!');
});
app.get('/r2-objects', async (c) => {
const list = await c.env.R2.list();
return c.text(JSON.stringify(list));
});
export default app;
http://localhost:8787/r2-objects にアクセスして先ほど登録したobjectが表示されていれば良さそうです。👇 手元で試した所作成した key: users のobjectが返ってきてました!
参考URL
Discussion