LoginSignup
0
0
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

データベースCloudflare D1とAstroサイトの連携(前半:ローカル版)

Posted at

目的

データベースCloudflare D1とAstroのサイトを連携します
今回の投稿の前半ではローカルのDBと接続し、別投稿の後半ではリモートのDB、つまりCloudflareのサーバー上のDBと接続します

つくるもの

こちらをベースにします

メモ(「タイトル」と「内容」のセット)をデータベースから取得し、表示することが今回の実装部分です

本編

全体の流れは、

  1. データベースを作成
  2. データベース定義を記述し、テーブルを追加するSQLファイルを生成
  3. SQLファイルを実行し、データベースにテーブルを追加
  4. テーブルにデータを追加
  5. Astroのエンドポイントにデータベースへのアクセス処理を追加

こんな感じです

パッケージのインストール

データベース関連のパッケージdrizzle-ormdrizzle-kitbetter-sqlite3、CloudflareのCLIwranglerをインストールします

npm install drizzle-orm drizzle-kit
npm install better-sqlite3
npm install wrangler

データベースの準備

データベースの定義を作成

データベースの定義を作成し、SQLファイルを生成します

src/db/schema.ts
import { text, integer, sqliteTable } from 'drizzle-orm/sqlite-core';

export const memos = sqliteTable('memos', {
  id: integer('id', { mode: 'number' }).primaryKey({ autoIncrement: true }),
  title: text('title'),
  content: text('content'),
});
npx drizzle-kit generate --schema=./src/db/schema.ts --dialect=sqlite

↓ 実行結果

> npx drizzle-kit generate --schema=./src/db/schema.ts --dialect=sqlite
drizzle-kit: v0.22.7
drizzle-orm: v0.31.2

1 tables
memos 3 columns 0 indexes 0 fks

[✓] Your SQL migration file ➜ drizzle\0000_flippant_sprite.sql 🚀

drizzle\0000_flippant_sprite.sqlが生成され、以降の工程ではこれを使います

000_flippant_sprite.sql
CREATE TABLE `memos` (
	`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
	`title` text,
	`content` text
);

CLIでログインする

npx wrangler loginでCLI経由でCloudflareにログインします

npx wrangler login

↓ 実行結果

> npx wrangler login  

 ⛅️ wrangler 3.61.0
-------------------

Attempting to login via OAuth...
Opening a link in your default browser: https://dash.cloudflare.com/oauth2/auth?response_type=code&client_id=XXXXXXXXX
Successfully logged in.
√ Would you like to help improve Wrangler by sending usage metrics to Cloudflare? ... no
Your choice has been saved in the following file: C:\Users\XXXXX\AppData\Roaming\xdg.config\.wrangler\metrics.json.

  You can override the user level setting for a project in `wrangler.toml`:     

   - to disable sending metrics for a project: `send_metrics = false`
   - to enable sending metrics for a project: `send_metrics = true`

以下のようにWebブラウザのログイン画面を経由します

image.png

image.png

データベースを作成する

CLIでデータベースを作成します

npx wrangler d1 create DB20240622

↓ 実行結果

> npx wrangler d1 create DB20240622

 ⛅️ wrangler 3.61.0
-------------------

✅ Successfully created DB 'DB20240622' in region APAC
Created your new D1 database.

[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "DB20240622"
database_id = "xxxx-xxxx-xxxx-xxxx-xxxx"

実行すると、Cloudflareのダッシュボードから、DB20240622というデータベースがつくられていることが確認できます

image.png

データベースのコンフィグファイルを作成

前述の操作で出力された設定記述をwrangler.tomlを作成して、記載します

wrangler.toml
[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "DB20240622"
database_id = "xxxx-xxxx-xxxx-xxxx-xxxx"

SQLファイルを実行

以下のコマンドで作成済みのSQLファイルを実行します
--localがローカルに対する操作を意味し、--remoteだとCloudflareサーバー上の本番のデータベースに対して操作します

npx wrangler d1 execute DB20240622 --local --file=./drizzle/0000_flippant_sprite.sql

↓ 実行結果

> npx wrangler d1 execute DB20240622 --local --file=./drizzle/0000_flippant_sprite.sql

 ⛅️ wrangler 3.61.0
-------------------

🌀 Executing on local database DB20240622 (9c560d0f-03b8-477b-93dc-9da3f3fc3c3e) from .wrangler\state\v3\d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.

Drizzle Studio向けにデータベース情報をセットする

drizzle.config.tsを作成し、urlに前述のコマンドで作成された.wrangler/state/v3/d1/miniflare-D1DatabaseObject/XXXX.sqliteを設定します

drizzle.config.ts
import { defineConfig } from "drizzle-kit"

export default defineConfig({
    dialect: "sqlite",
    dbCredentials: {
        url: ".wrangler/state/v3/d1/miniflare-D1DatabaseObject/5f5a9139cd06e3a10deff13ceaa03bbc42bab7d3570f17a28f257aac74162e52.sqlite",
    },
})

データベースをDrizzle Studioで確認する

drizzle-kitに含まれているDrizzle Studioを使い、Webブラウザからデータベースにアクセスしてみます

コマンドは以下の通りです

npx drizzle-kit studio

↓ 実行結果

> npx drizzle-kit studio    
drizzle-kit: v0.22.7
drizzle-orm: v0.31.2

No config path provided, using default path
Reading config file 'E:\github\20240622\drizzle.config.ts'

 Warning  Drizzle Studio is currently in Beta. If you find anything that is not 
working as expected or should be improved, feel free to create an issue on GitHub: https://github.com/drizzle-team/drizzle-kit-mirror/issues/new or write to us 
on Discord: https://discord.gg/WcRKz2FFxN

Drizzle Studio is up and running on https://local.drizzle.studio

https://local.drizzle.studioにアクセスすると、以下のようにデータベースを確認できます
作成済みのmemosテーブルが存在することがわかります

image.png

データベースにデータを追加しておく

続いて、データを追加してみます

npx wrangler d1 execute DB20240622 --local --command="insert into memos (title,content) values('Learn D1','contentcontent')"

↓ 実行結果

> npx wrangler d1 execute DB20240622 --local --command="insert into memos (title,content) values('Learn D1','contentcontent')"

 ⛅️ wrangler 3.61.0
-------------------

🌀 Executing on local database DB20240622 (xxx-xxx-xx-xxxx-xxxx) from .wrangler\state\v3\d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.

Drizzle Studioで確認すると、データが追加されています

image.png

ついでに、もう1件のデータを追加しておきました

image.png

Astroからデータベースへアクセス

AstroにCloudflareアダプター追加

Cloudflareにアクセスできるようにアダプターを追加します
@astrojs/cloudflareを追加し、その後、astro.config.mjsへ設定を追加します

npx astro add @astrojs/cloudflare

↓ 実行結果

> npx astro add @astrojs/cloudflare
✔ Resolving packages...

  Astro will run the following command:
  If you skip this step, you can always run it yourself later

 ╭──────────────────────────────────────────╮
 │ npm install @astrojs/cloudflare@^11.0.0  │
 ╰──────────────────────────────────────────╯

√ Continue? ... yes
✔ Installing dependencies...

  Check our deployment docs for @astrojs/cloudflare to update your "adapter" config.
  
   success  Configuration up-to-date.

設定は以下のように、adapter: cloudflare()を追加します

astro.config.mjs
import { defineConfig } from 'astro/config';

import vue from "@astrojs/vue";
import cloudflare from "@astrojs/cloudflare";

// https://astro.build/config
export default defineConfig({
  integrations: [vue()],
  output: 'server',
  adapter: cloudflare()
});

エンドポイントへデータベースへのアクセス処理を追加

エンドポイントの処理では、locals.runtime.envから環境変数にアクセスできます
このとき、.env.d.tsに記述を追加しないといけない気がしますが、今のところは追加しなくとも動いているので、ひとまず無視しておきます

.env.d.tsに必要な気がする記載
.env.d.ts
/// <reference types="astro/client" />

type D1Database = import("@cloudflare/workers-types").D1Database;
type ENV = {
	DB: D1Database;
};

// use a default runtime configuration (advanced mode).
type Runtime = import("@astrojs/cloudflare").Runtime<ENV>;
declare namespace App {
  interface Locals extends Runtime {}
}

必要そうだったら、上記をご参考にどうぞ

src/pages/v1/memo.tsは以下のように書きました
データベースにデータが存在しなければダミーデータを使用するようにしていますが、書き方が適切かどうかはわかりません、適当です

src/pages/v1/memo.ts
import { drizzle } from 'drizzle-orm/d1';
import { memos } from "../../db/schema";
import type { Runtime } from '@astrojs/cloudflare';

export async function GET({ locals }: { locals: Runtime }) {
    const envDB = locals.runtime.env.DB as D1Database;
    const db = drizzle(envDB);
    
    let memo = await db.select().from(memos);
    
    if (!memo || (Array.isArray(memo) && memo.length === 0)) {
        memo = [{ id: 1, title: "DUMMY1", content: "content1" }, { id: 2, title: "DUMMY2", content: "content2" }]
    }

    return new Response(
        JSON.stringify({
            body: { memos: memo }
        }), { status: 200 }
    );
}

動作確認

動作確認をしてみます

npm run dev

image.png

よさそうです

まとめ

以上で、ローカルのデータベースにアクセスして、データを取得することができました

後半ではリモートの、Cloudflareのデータベースに対して、処理をおこなってみます

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0