Denoflare で Cloudflare Workers から D1 を使う

Cloudflare の Workers から D1 を使う上で、せっかくなら Deno を使ってみたいと思い、公式でも紹介されている Denoflare を使ってみました。デプロイを実行して JSON をレスポンスさせるまでをメモします。

注意事項

2024/2/20 時点で、Cloudflare D1 はベータ版とされ、Denoflare もメジャーバージョンが 0 となります。

今後も使用する機会があり且つ変更があった場合には随時追記していきます。

下準備

Cloudflare への登録手順は省きます。

バージョン情報

  • deno@1.40.5
  • denoflare@0.6.0

開発環境

  • Editor: VSCode
  • OS: Linux(OpenSUSE)

各種インストール

Deno

実行環境
curl -fsSL https://deno.land/install.sh | sh

https://docs.deno.com/runtime/manual/

VSCode 拡張機能

vscode-deno

Denoflare

deno install --unstable-worker-options --allow-read --allow-net --allow-env --allow-run --name denoflare --force \
https://raw.githubusercontent.com/skymethod/denoflare/v0.6.0/cli/cli.ts

https://denoflare.dev/cli/

ファイル構成, パッケージ

.
├── .denoflare
├── deno.json
├── src
│   └── index.ts
└── .vscode
    └── settings.json

コーディング

下記で各ファイルの内容と簡単な説明をします。

.denoflare

{
    "$schema": "https://raw.githubusercontent.com/skymethod/denoflare/v0.6.0/common/config.schema.json",
    "scripts": {
        "hello": {
            "path": "./src/index.ts",
            "bindings": {
                "DB": { "d1DatabaseUuid": "<D1 DB ID>" },
            },
            "localPort": 3030,
        }
    },
    "profiles": {
        "account1": {
            "accountId": "<YOUR ACCOUNT ID>",
            "apiToken": "<YOUR API TOKEN>"
        }
    }
}

Denoflare を使用する際の設定ファイルです。ほとんどは公式のガイドをそのまま使っています。

変更点としては、下記のような感じです。記載していませんが accountIdapiToken も変更しています。

-        "hello-local": {
-            "path": "index.ts",
-            "localPort": 3030
+        "hello": {
+            "path": "./src/index.ts",
+            "bindings": {
+                "DB": { "d1DatabaseUuid": <D1 DB ID> },
+            },
+            "localPort": 3030,

hello は Workers のスクリプトの識別子となり、Denoflare からのデプロイもこの識別子を使い、Cloudflare 上でも登録されます。path で実行されるスクリプトのパスを指定するので、実行ファイル名自体はなんでもOKです。

bindings.env のようにスクリプト内で使用できる環境変数になります。d1DatabaseUuid の値は Workers から D1 に接続するために必要になります。

DB.d1DatabaseUuidaccountIdapiToken の取得方法については後で説明します。

deno.json

Deno 用の設定ファイルです。

@cloudflare/workers-types とは、 Workers のために用意された型定義です。

このままでは使えませんが、詳しくは追って説明します。

{
  "compilerOptions": {
    "types": ["@cloudflare/workers-types"]
  },
  "imports": {
    "@cloudflare/workers-types": "https://esm.sh/@cloudflare/workers-types@4.20240208.0/experimental"
  }
}

src/index.ts

Workers の実行スクリプトで、D1 にある posts テーブルのデータを返す簡単なものです。

先ほど .denoflareDB.d1DatabaseUuid という変数を設定していましたが、これは fetch の第二引数で参照可能です。ただし、d1DatabaseUuid のように特定のキーバリューを持つ環境変数の場合は、Cloudflare の各サービスを使用するための関数がバインドされます。なので、スクリプト内では DB 変数から prepare という関数にアクセスできているというわけです。

D1Database という型は @cloudflare/workers-types に定義があるので、直接 import せずとも設定に応じて VSCode が認識してくれるようになります。

interface Env {
  DB: D1Database;
}

export default {
  async fetch(request: Request, env: Env) {
    const { results } = await env.DB.prepare("SELECT * FROM posts").all();

    try {
      return Response.json(results);
    } catch (e) {
      return new Response(e.message);
    }
  },
};

.vscode/settings.json

VSCode の設定ファイルです。拡張機能がインストール済みであれば設定が可能です。

deno.enable でそのプロジェクト内での Deno のサポート(Deno のAPIへの参照やインポート時の解消など)を有効にします。

{
  "deno.enable": true,
  "deno.config": "./deno.json"
}

Workers スクリプトを公開してアクセスするまで

コードについては前述でそろっているので、解説しながら公開していきます。

パッケージのキャッシュ

Deno は Node.js のようにパッケージのインストールを npm install のように実行せず、コードや設定ファイル内に必要なパッケージを記載しておくことで、スクリプトの実行時にインストールしてくれます。

VSCode から src/index.ts を見ると、スクリプト実行前のため、 D1Database の定義未解決のエラーが発生していることがわかります。

Ctrl+Shift+P などから VSCode のコマンドパレットを呼び出し Deno: Cache Dependencies を実行することでパッケージがキャッシュされ、しばらくすると型エラーが解消されるようになります。

Denoflare から Cloudflare に接続するための設定

まだ .denoflareprofiles にプロファイル情報(accountIdapiToken)を記載していないので、 Denoflare からはデプロイなどができません。

下記の手順でそれぞれ取得します。

  1. Cloudflare のダッシュボードにアクセスして、左サイドメニューから「Workers & Pages」にアクセスしてください。画面右側に表示されている「Account ID」が accountId になります(URL の文字列も ID です)。
  2. 続いて画面右上のアカウントアイコンから「My Profile」にアクセスし、左サイドメニューから「API Tokens」にアクセスしてください。
  3. 「Create Token」ボタンを押して表示された画面下部「Create Custom Token」ボタンを押してください。
  4. 「Token name」は「Access D1 From Workers」など、適当なものを入力してください。
  5. 「Permissions」には下記の設定を追加します。(src/index.ts を実行するための最低限の権限)
  • Account, D1, Edit
  • Account, Workers Script, Edit
  1. 「Account Resources」に自分のアカウントを選択してください。
  2. ページ下部の「Continue to summary」ボタンを押し、次のページで「Create Token」ボタンを押してください。
  3. 次のページに表示されたトークンが apiToken になります。

上記で得た accountIdapiToken.denoflare に記載することでサービスにアクセスできます。

プロジェクトのディレクトリで denoflare d1 list コマンドを実行して、エラー表示なく空のリストが帰ってきたら成功です。

D1 DB、テーブルの作成とデータ挿入

src/index.ts では posts テーブルを参照していますが、まだ D1 にはテーブルがありませんし、 denoflare d1 list コマンドを実行して分かる通り DB 自体も作成されていません。

まずは D1 に test-db DB を denoflare d1 create test-db コマンドを実行して作成してください。

再度 denoflare d1 list を実行することで作成されたことが確認できます。その中に記載のある uuid.denoflared1DatabaseUuid に設定してください。これで先ほど説明した通り、デプロイ後のスクリプト実行時、D1 の関数がバインドされて使用することができます。

続いてテーブルを作り、データを挿入します。テーブル操作も下記の通り denoflare コマンド経由で実行可能です。

# test-db に対して posts テーブルを作成
denoflare d1 query test-db --sql "CREATE TABLE posts (id INTEGER PRIMARY KEY, desc TEXT);"
# posts テーブルにデータ挿入
denoflare d1 query test-db --sql "INSERT INTO posts VALUES (1, \"test1\"), (2, \"test2\");"
# posts テーブルを参照 ※`src/index.ts` と同じSQL
denoflare d1 query test-db --sql "SELECT * FROM posts;"

これで参照先 DB データの準備もOKです。

Workers スクリプトのデプロイ

プロジェクトのディレクトリで denoflare push hello コマンドを実行して下さい。hello の部分は .denoflarescripts に記載した識別子となります。

エラーなど発生しなければ、これでスクリプトが公開されました。

Cloudflare のダッシュボードにアクセスし、左サイドメニューから「Workers & Pages」にアクセスすると、「hello」というアプリケーションが追加されていることを確認できます。

「hello」をクリックして詳細ページにアクセスし、「Preview」に表示されたURLにアクセスすることで、スクリプト通り、posts のデータを json で返すレスポンスが確認できます。

参考サイト