☁️

Cloudflare Workers + D1を試してみた

に公開

個人開発をやっているといつも
「データベース何を使おう」、「どこにホスティングしよう」とかいろいろ悩むのですが
今回は聞いたことあるけど使ったことがなかったCloudeflareのサービスを使ってみようと思いたち、
ついでにやったことを記事にしてみました。

📝 Cloudflareとは?

https://www.cloudflare.com/ja-jp/learning/what-is-cloudflare/

Cloudflareは、Webサイトやアプリを高速かつ安全に配信するためのグローバルネットワークサービスです。
CDN(コンテンツ配信)、DDoS対策、WAF、DNSなどをワンクリックで利用でき、開発者向けにはサーバレス基盤「Workers」やデータベース「D1」も提供しています。

Cloudflare Workers

サーバレス関数です!lambdaみたいなものです!

Cloudflare D1

Cloudflare Workersから利用できるSQLiteベースのサーバレスDBです!

個人的な魅力ポイント

  • 時間ではなく読み書きベースの課金
  • 無料枠も大きい
  • freeアカウントでもDBが10個も作れる

詳しくは公式の料金表を参照ください!

https://developers.cloudflare.com/d1/platform/pricing/

🎯 今回やること

今回はクライアント ↔︎ API (Workers(Hono)) ↔︎ DB (D1)の構成で、
DBに入ってるTodoリストをresponseするだけのAPIを作成したいと思います!

workersで使用するフレームワークはHonoにしました!

💻 環境

$ npm -v
11.4.2

$ node -v
v22.14.0

作業前にCloudeflareのアカウントは事前に作成しました!

⚙️ まずはWorkersを作成する

npm create cloudflare@latest -- worker

いろいろ尋ねられるのですが、以下のように設定しました!

What would you like to start with?
→ ● Framework Starter→● Hono

Do you want to use git for version control?
→ Yes

Do you want to deploy your application?
→ No

念のためnpm run devでapiが立ち上がるのも確認しておきます!

apiが立ち上がった後の画面

🗄️ D1の作成

次にd1 DBを作成します!

npx wrangler@latest d1 create todo-app

ダッシュボードを確認すると新しくd1 DBが作成されたことがわかります!

ダッシュボードの画面
以下のコマンドでも確認できます

npx wrangler d1 list
~/projects/todo-d1/worker (main) npx wrangler d1 list

 ⛅️ wrangler 4.25.0
───────────────────
┌──────────────────────────────────────┬──────────┬──────────────────────────┬────────────┬────────────┬───────────┐
 uuid name created_at version num_tables file_size
├──────────────────────────────────────┼──────────┼──────────────────────────┼────────────┼────────────┼───────────┤
 1b421315-7d2e-4fb9-8034-660862e4efcf todo-app 2025-07-22T10:02:17.238Z production 0 12288
└──────────────────────────────────────┴──────────┴──────────────────────────┴────────────┴────────────┴───────────┘

🔗 WorkerとD1を紐付け

先ほど作ったworkerプロジェクト内にwrangler.jsoncがあるのでこのファイルに
d1_databasesを追記します!

  • binding
    • worker内からd1を参照するときに使う名前 (javascriptの変数名のルールに従う必要あり!)
  • database_name
    • 先ほど作ったdatabaseの名前
  • database_id
    • 先ほど作ったdatabaseのuuid
{
 "$schema": "node_modules/wrangler/config-schema.json",
 "name": "worker",
 "main": "src/index.ts",
 "compatibility_date": "2025-07-19",
 "assets": {
  "binding": "ASSETS",
  "directory": "./public"
 },
 "observability": {
  "enabled": true
 },
+ "d1_databases": [
+ {
+  "binding": "TODO_DB",
+  "database_name": "todo-app",
+  "database_id": "d4704aeb-0299-4396-b71c-6f239bb68db3"
+ }
 ]
}

migration

マイグレーションファイルを作成します

npx wrangler d1 migrations create <binding> <好きな名>

migrationsディレクトリ作っていい?と聞かれるのでyを押します。

~/todo-d1/worker npx wrangler d1 migrations create TODO_DB init

 ⛅️ wrangler 4.25.0
───────────────────
 No migrations folder found. Set `migrations_dir` in your wrangler.json file to choose a different path.
Ok to create /Users/haraguchi/projects/todo-d1/worker/migrations? yes
 Successfully created Migration '0001_init.sql'!

The migration is available for editing here
/Users/haraguchi/projects/todo-d1/worker/migrations/0001_init.sql

migrationsディレクトリの中に0001_init.sqlができていると思います!

ここに作りたいテーブルのSQLを記載します!
今回は以下のようなsqlを書きました!

-- Migration number: 0001   2025-07-19T06:30:04.036Z
-- 古いテーブルがあれば削除
DROP TABLE IF EXISTS Todos;

-- Todo テーブル作成
CREATE TABLE IF NOT EXISTS Todos (
  Id         INTEGER PRIMARY KEY AUTOINCREMENT,
  Title      TEXT NOT NULL,
  Done       INTEGER DEFAULT 0,
  CreatedAt  TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
);

-- 初期データの投入
INSERT INTO Todos (Title, Done)
VALUES
  ('洗濯物を干す', 0),
  ('エルデンリングをする', 1),
  ('草むしり', 0);

apply

migrationファイルをローカル用のd1にapplyします!

npx wrangler d1 migrations apply <binding>
~/todo-d1/worker npx wrangler d1 migrations apply TODO_DB

 ⛅️ wrangler 4.25.0
───────────────────
Migrations to be applied:
┌───────────────┐
 name
├───────────────┤
 0001_init.sql
└───────────────┘
 About to apply 1 migration(s)
Your database may not be available to serve requests during the migration, continue? yes
🌀 Executing on local database TODO_DB (d4704aeb-0299-4396-b71c-6f239bb68db3) from .wrangler/state/v3/d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.
🚣 4 commands executed successfully.
┌───────────────┬────────┐
 name status
├───────────────┼────────┤
 0001_init.sql
└───────────────┴────────┘

applyされてtodosにデータが入っていることを確認します!
executeを使用すると作ったローカルのd1DBに対してSQLを使用できます

~/todo-d1/worker npx wrangler d1 execute TODO_DB --command "SELECT * FROM Todos;"

 ⛅️ wrangler 4.25.0
───────────────────
🌀 Executing on local database TODO_DB (d4704aeb-0299-4396-b71c-6f239bb68db3) from .wrangler/state/v3/d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.
🚣 1 command executed successfully.
┌────┬──────────────────────┬──────┬──────────────────────────┐
 Id Title Done CreatedAt
├────┼──────────────────────┼──────┼──────────────────────────┤
 1 洗濯物を干す 0 2025-07-19T06:49:01.952Z
├────┼──────────────────────┼──────┼──────────────────────────┤
 2 エルデンリングをする 1 2025-07-19T06:49:01.952Z
├────┼──────────────────────┼──────┼──────────────────────────┤
 3 草むしり 0 2025-07-19T06:49:01.952Z
└────┴──────────────────────┴──────┴──────────────────────────┘

問題なくテーブルが作成できていそうなので次はリモートのd1にapplyします!
applyコマンドに--remoteオプションをつけるだけです!

~/todo-d1/worker npx wrangler d1 migrations apply TODO_DB --remote

 ⛅️ wrangler 4.25.0
───────────────────
Migrations to be applied:
┌───────────────┐
 name
├───────────────┤
 0001_init.sql
└───────────────┘
 About to apply 1 migration(s)
Your database may not be available to serve requests during the migration, continue? yes
🌀 Executing on remote database TODO_DB (d4704aeb-0299-4396-b71c-6f239bb68db3):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 4 commands in 1.1784ms
┌───────────────┬────────┐
 name status
├───────────────┼────────┤
 0001_init.sql
└───────────────┴────────┘

webコンソールから確認したところちゃんとテーブルできていることが確認できました!
(マイグレーションテーブルとシーケンステーブルも一緒に作ってくれるみたいです)

4

🚀 api作る

src/index.tsに以下を貼り付けます!

import { Hono } from "hono";


type Bindings = {
    // 設定したbinding名に書き換えてください!
    TODO_DB: D1Database
}

type Todo = {
    Id: number
    Title: string
    Done: number
    CreatedAt: string
}


const app = new Hono<{ Bindings: Bindings }>();

app.get("/todos", async (c) => {
    const { results } = await c.env.TODO_DB
        .prepare("SELECT * FROM Todos ORDER BY Id DESC")
        .all<Todo>()
    return c.json(results)
})


export default app;

開発環境を立ち上げて

npm run dev

curl投げてtodoリストが返ってくればとりあえずOKです!

curl http://localhost:8787/todos
[
  {"Id":3,"Title":"草むしり","Done":0,"CreatedAt":"2025-07-19T06:49:01.952Z"},
  {"Id":2,"Title":"エルデンリングをする","Done":1,"CreatedAt":"2025-07-19T06:49:01.952Z"},
  {"Id":1,"Title":"洗濯物を干す","Done":0,"CreatedAt":"2025-07-19T06:49:01.952Z"}
]

最後にdeployしてapiが使えるか試してみましょう!

npm run deploy

> deploy
> wrangler deploy --minify


 ⛅️ wrangler 4.25.0
───────────────────
🌀 Building list of assets...
 Read 1 file from the assets directory /Users/haraguchi/projects/todo-d1/worker/public
🌀 Starting asset upload...

Total Upload: 20.01 KiB / gzip: 8.11 KiB
Your Worker has access to the following bindings:
Binding                          Resource
env.TODO_DB (todo-app)      D1 Database
env.ASSETS                       Assets

Uploaded worker (18.95 sec)
Deployed worker triggers (1.23 sec)
  https://worker.haraguchi-shoya.workers.dev
Current Version ID: 14888667-709a-404c-a6fd-34c914b6aac7

使えました!

curl https://worker.haraguchi-shoya.workers.dev/todos
[
  {"Id":3,"Title":"草むしり","Done":0,"CreatedAt":"2025-07-19T07:20:13.462Z"},
  {"Id":2,"Title":"エルデンリングをする","Done":1,"CreatedAt":"2025-07-19T07:20:13.462Z"},
  {"Id":1,"Title":"洗濯物を干す","Done":0,"CreatedAt":"2025-07-19T07:20:13.462Z"}
]

🎉 まとめ

今回は、Cloudflare Workers + D1を使って超シンプルなapiを作成しました!

できたこと

  • Cloudflare Workers を使ったAPIの実装
  • Cloudflare D1でサーバーレスなデータベースを構築

良かった点

  • 開発体験が良い: ローカルD1での開発→リモートへのデプロイが簡単!
  • コスパが良い: D1は読み書き回数ベースの課金で、無料枠も多い!
  • シンプルな構成: Workers + D1の組み合わせで、インフラ管理不要!

Cloudflare D1は無料枠が大きく、読み書き回数ベースの課金体系なので、個人開発や小規模プロジェクトにぴったりです。

そしてサーバーレスで簡単にAPIとDBを構築できるのが魅力的でした!

ぜひ皆さんも試してみてください!

参考リンク


Curious Vehicle では新しい仲間を募集しています!

募集中の職種については弊社のホームページをご覧ください。
https://www.curicle.jp/recruit/

Discussion