【備忘録】Cloudflare D1 + Hono + Drizzle ORM 環境構築手順

# はじめに
この手順では、Cloudflare Workers上で動作するHonoアプリケーションを構築し、
Cloudflare D1データベースとDrizzle ORMを組み合わせてデータベースを管理する環境を
セットアップする方法を記載します。
(UIが日々更新されるので現時点での最新の情報を残す事が目的です。)

# 環境構築手順

## Cloudflareアカウントの作成
まず、Cloudflareアカウントを作成します。
下記にアクセスしてアカウントを作成してください。
https://www.cloudflare.com/ja-jp/

## Honoプロジェクトの作成
次に、Honoを使ってプロジェクトを初期化します。
以下のコマンドを実行してください：
今回は`Bun`をパッケージマネージャとして使用します。

```
bun create hono@latest
```

対話形式で以下の質問に答えていきます：

```
Target directory: my-app（任意のディレクトリ名を指定）
Which template do you want to use?: cloudflare-workers（Cloudflare Workers向けテンプレートを選択）
Do you want to install project dependencies?: yes（依存関係をインストール）
Which package manager do you want to use?: bun（Bunをパッケージマネージャとして使用）
```
これでテンプレートがクローンされ、依存関係がインストールされます。

## Wranglerのインストール
CloudflareのCLIツールであるWranglerをグローバルインストールします。
初回のみ以下のコマンドを実行します。

```
sudo bun i -g wrangler
```

## 必要なライブラリのインストール
プロジェクトに必要なライブラリを追加します。
以下のコマンドを実行してください。

```
bun add drizzle-orm dotenv
bun add -D drizzle-kit tsx
bun add --dev @cloudflare/workers-types
```

+ drizzle-orm: Drizzle ORM本体
+ dotenv: 環境変数の管理
+ drizzle-kit と tsx: 開発ツール（マイグレーション用）
+ @cloudflare/workers-types: Cloudflare Workersの型定義


## Cloudflare D1データベースの作成
D1データベースを作成します。まず、WranglerでCloudflareにログインします。

```
wrangler login
```

次に、データベースを作成します（my-database-nameは任意の名前に変更可能）

```
bun wrangler d1 create my-database-name
```

成功すると、以下のような設定情報が返されます。

```
{
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "my-database-name",
      "database_id": "***"
    }
  ]
}
```
この情報をプロジェクトの `wrangler.jsonc` ファイルにコピーします。
具体的には、以下のように追加します（database_idは実際の値に置き換えてください）。
`migrations_dir`は必要に応じて追加してください
```jsonc:wrangler.jsonc
"d1_databases": [
  {
    "binding": "DB",
    "database_name": "my-database-name",
    "database_id": "***",
    "migrations_dir" : "drizzle" ★追加
  }
]
```

## スキーマの作成
Drizzle ORMで使用するデータベーススキーマを定義します。
`src/db/schema.ts` を作成し、以下を記述します。

```ts:src/db/schema.ts
import { int, sqliteTable, text } from "drizzle-orm/sqlite-core";

export const usersTable = sqliteTable("users_table", {
  id: int().primaryKey({ autoIncrement: true }),
  name: text().notNull(),
  age: int().notNull(),
  email: text().notNull().unique(),
});
```

テーブル名、カラム名などは実際の値に置き換えてください。

## Drizzle設定ファイルの作成
Drizzleの設定ファイル `drizzle.config.ts` を作成します。以下を記述します：

```typescript: drizzle.config.ts
import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';

export default defineConfig({
  out: './drizzle',
  schema: './src/db/schema.ts',
  dialect: 'sqlite',
  driver: 'd1-http',
  dbCredentials: {
    accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
    databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
    token: process.env.CLOUDFLARE_D1_TOKEN!,
  },
});
```

## 環境変数の設定
`.env` ファイルを作成し、Cloudflareの認証情報を記載します：
```.env
CLOUDFLARE_ACCOUNT_ID=***
CLOUDFLARE_DATABASE_ID=***
CLOUDFLARE_D1_TOKEN=***
```

### 各値の取得方法：
Cloudflareのダッシュボードから確認できます。
+ CLOUDFLARE_ACCOUNT_ID: CloudflareダッシュボードのURLに含まれるID
+ CLOUDFLARE_DATABASE_ID: 「Storage & Database > D1 SQL Database」で確認
+ CLOUDFLARE_D1_TOKEN: 右上の「Profile > User API Tokens」から
「Create Custom Token」を作成（権限は「D1:Edit」）


## マイグレーションの実行
スキーマをデータベースに適用するために、マイグレーションを行います。
以下の2つのコマンドを実行します。

```
# マイグレーションファイルの作成
npx drizzle-kit generate

# ローカルに作成
npx wrangler d1 migrations apply <DATABASE_NAME> --local

# リモートに作成
npx wrangler d1 migrations apply <DATABASE_NAME> --remote
```

+ generate: マイグレーションファイルを生成
+ migrate: 生成したマイグレーションを適用

ここまでで問題が無ければ、
Cloudflareのダッシュボードから「Storage & Database > D1 SQL Database」
にテーブルが作成されているはずです。