Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

プロキシ Worker を使って D1 にアクセスする API を構築する

最終更新 Markdown で表示Agent セットアップ

このチュートリアルでは、D1 データベースに対して安全にクエリを実行できる API の作成方法を学びます。

Worker や Pages プロジェクトの外から D1 データベースへアクセスしたい場合、アクセス制御をカスタマイズしたい場合、クエリ可能なテーブルを制限したい場合に役立ちます。

D1 組み込みの REST API は、グローバルな Cloudflare API レート制限 が適用されるため、管理用途に向いています。

Worker プロジェクトの外から D1 データベースへアクセスするには、Worker で API を作成します。アプリケーションはその API と安全にやり取りして、D1 クエリを実行できます。

前提条件

  1. Cloudflare アカウント にサインアップします。
  2. Node.js をインストールします。
  3. 既存の D1 データベースがあること。D1 の始め方 を参照してください。

Node.js のバージョン管理

権限の問題を避け、Node.js のバージョンを切り替えるには、Voltanvm などの Node バージョンマネージャーを使います。このガイドで後述する Wrangler には、16.17.0 以降の Node バージョンが必要です。

1. 新しいプロジェクトを作成する

API を作成してデプロイするための、新しい Worker を作成します。

  1. 次を実行して、d1-http という名前の Worker を作成します。

    npm create cloudflare@latest -- d1-http

    セットアップでは、次のオプションを選びます。

    • What would you like to start with? では、Hello World example を選びます。
    • Which template would you like to use? では、Worker only を選びます。
    • Which language do you want to use? では、TypeScript を選びます。
    • Do you want to use git for version control? では、Yes を選びます。
    • Do you want to deploy your application? では、No を選びます(デプロイ前にいくつか変更します)。
  2. 新しいプロジェクトディレクトリに移動して、開発を始めます。

    cd d1-http

2. Hono をインストールする

このチュートリアルでは、Express.js 風のフレームワークである Hono を使って API を構築します。

  1. このプロジェクトで Hono を使うため、npm でインストールします。

    npm i hono

3. API_KEY を追加する

API へ認証付きで呼び出すには、API キーが必要です。API キーを安全に保つため、secret として追加します。

  1. ローカル開発用に、d1-http のルートディレクトリへ .dev.vars ファイルを作成します。

  2. ファイルへ、次のように API キーを追加します。

    .dev.varsbash
    API_KEY="YOUR_API_KEY"

    YOUR_API_KEY を有効な文字列に置き換えます。次のコマンドで値を生成することもできます。

    openssl rand -base64 32

4. アプリケーションを初期化する

アプリケーションを初期化するには、必要なパッケージをインポートし、新しい Hono アプリケーションを初期化し、次のミドルウェアを設定します。

  • Bearer Auth: API に認証を追加します。
  • Logger: リクエストとレスポンスの流れを監視できます。
  • Pretty JSON: JSON レスポンス本文の "JSON pretty print" を有効にします。
  1. src/index.ts ファイルの内容を、次のコードで置き換えます。

    src/index.tsts
    import { Hono } from "hono";
    import { bearerAuth } from "hono/bearer-auth";
    import { logger } from "hono/logger";
    import { prettyJSON } from "hono/pretty-json";
    
    type Bindings = {
    	API_KEY: string;
    };
    
    const app = new Hono<{ Bindings: Bindings }>();
    
    app.use("*", prettyJSON(), logger(), async (c, next) => {
    	const auth = bearerAuth({ token: c.env.API_KEY });
    	return auth(c, next);
    });

5. API エンドポイントを追加する

  1. 次のスニペットを src/index.ts に追加します。

    src/index.tsts
    
    // Paste this code at the end of the src/index.ts file
    
    app.post("/api/all", async (c) => {
    	return c.text("/api/all endpoint");
    });
    
    app.post("/api/exec", async (c) => {
    	return c.text("/api/exec endpoint");
    });
    
    app.post("/api/batch", async (c) => {
    	return c.text("/api/batch endpoint");
    });
    
    export default app;

    これにより、次のエンドポイントが追加されます。

    • POST /api/all
    • POST /api/exec
    • POST /api/batch
  2. 次のコマンドで開発サーバーを起動します。

    npm run dev
  3. API をローカルでテストするには、2 つ目のターミナルを開きます。

  4. 2 つ目のターミナルで、次の cURL コマンドを実行します。YOUR_API_KEY.dev.vars ファイルで設定した値に置き換えます。

    curl -H "Authorization: Bearer YOUR_API_KEY" "http://localhost:8787/api/all" --data '{}'

    次の出力になります。

    /api/all endpoint
  5. 1 つ目のターミナルで x を押して、ローカルサーバーを停止します。

Hono アプリケーションの準備ができました。ほかのエンドポイントをテストしたり、必要に応じてエンドポイントを追加したりできます。この時点では、API はデータベースからの情報をまだ返しません。次の手順でデータベースを作成し、バインディングを追加し、データベースとやり取りするようにエンドポイントを更新します。

6. データベースを作成する

まだ D1 データベースがない場合は、wrangler d1 create で新しいデータベースを作成できます。

  1. ターミナルで次を実行します。

    npx wrangler d1 create d1-http-example

    Cloudflare アカウントへのログインを求められる場合があります。ログインすると、コマンドは新しい D1 データベースを作成します。ターミナルに次のような出力が表示されます。

     Successfully created DB 'd1-http-example' in region EEUR
    Created your new D1 database.
    
    [[d1_databases]]
    binding = "DB" # i.e. available in your Worker on env.DB
    database_name = "d1-http-example"
    database_id = "1234567890"

表示された database_namedatabase_id を控えます。バインディング を作成して、このデータベースを参照します。

7. バインディングを追加する

  1. d1-http フォルダーから、Wrangler の設定ファイルである Wrangler ファイルを開きます。

  2. ファイルに次のバインディングを追加します。database_namedatabase_id が正しいことを確認します。

    {
      "d1_databases": [
        {
          "binding": "DB", // i.e. available in your Worker on env.DB
          "database_name": "d1-http-example",
          "database_id": "1234567890"
        }
      ]
    }
    [[d1_databases]]
    binding = "DB"
    database_name = "d1-http-example"
    database_id = "1234567890"
  3. src/index.ts ファイルで、Bindings 型に DB: D1Database を追加して更新します。

    type Bindings = {
    	DB: D1Database;
    	API_KEY: string;
    };

これで、Hono アプリケーションからデータベースにアクセスできます。

8. テーブルを作成する

新しく作成したデータベースにテーブルを作成します。

  1. d1-http フォルダー内に、schemas という新しいフォルダーを作成します。

  2. schema.sql という新しいファイルを作成し、次の SQL 文を貼り付けます。

    schema.sqlsql
    DROP TABLE IF EXISTS posts;
    CREATE TABLE IF NOT EXISTS posts (
    	id integer PRIMARY KEY AUTOINCREMENT,
    	author text NOT NULL,
    	title text NOT NULL,
    	body text NOT NULL,
    	post_slug text NOT NULL
    );
    INSERT INTO posts (author, title, body, post_slug) VALUES ('Harshil', 'D1 HTTP API', 'Learn to create an API to query your D1 database.','d1-http-api');

    このコードは、posts という名前のテーブルがあれば削除し、idauthortitlebodypost_slug フィールドを持つ新しいテーブル posts を作成します。その後、INSERT 文でテーブルにデータを投入します。

  3. ターミナルで次のコマンドを実行し、このテーブルを作成します。

    npx wrangler d1 execute d1-http-example --file=./schemas/schema.sql

実行が成功すると、データベースに新しいテーブルが追加されます。

9. データベースをクエリする

アプリケーションから D1 データベースへアクセスできるようになりました。この手順では、データベースをクエリして結果を返すように API エンドポイントを更新します。

  1. src/index.ts ファイルのコードを、次のように更新します。

    src/index.tsts
    // Update the API routes
    
    /**
    * Executes the `stmt.run()` method.
    * https://developers.cloudflare.com/d1/worker-api/prepared-statements/#run
    */
    
    app.post('/api/all', async (c) => {
    		return c.text("/api/all endpoint");
    	try {
    		let { query, params } = await c.req.json();
    		let stmt = c.env.DB.prepare(query);
    		if (params) {
    			stmt = stmt.bind(params);
    		}
    
    		const result = await stmt.run();
    		return c.json(result);
    	} catch (err) {
    		return c.json({ error: `Failed to run query: ${err}` }, 500);
    	}
    });
    
    /**
    * Executes the `db.exec()` method.
    * https://developers.cloudflare.com/d1/worker-api/d1-database/#exec
    */
    
    app.post('/api/exec', async (c) => {
    		return c.text("/api/exec endpoint");
    	try {
    		let { query } = await c.req.json();
    		let result = await c.env.DB.exec(query);
    		return c.json(result);
    	} catch (err) {
    		return c.json({ error: `Failed to run query: ${err}` }, 500);
    	}
    });
    
    /**
    * Executes the `db.batch()` method.
    * https://developers.cloudflare.com/d1/worker-api/d1-database/#batch
    */
    
    app.post('/api/batch', async (c) => {
    		return c.text("/api/batch endpoint");
    	try {
    		let { batch } = await c.req.json();
    		let stmts = [];
    		for (let query of batch) {
    			let stmt = c.env.DB.prepare(query.query);
    			if (query.params) {
    				stmts.push(stmt.bind(query.params));
    			} else {
    				stmts.push(stmt);
    			}
    		}
    		const results = await c.env.DB.batch(stmts);
    		return c.json(results);
    	} catch (err) {
    		return c.json({ error: `Failed to run query: ${err}` }, 500);
    	}
    });
    ...

上記のコードでは、エンドポイントが queryparams を受け取るように更新されています。これらのクエリとパラメーターは、データベースとやり取りするそれぞれの関数へ渡されます。

  • クエリが成功すると、データベースからの結果を受け取ります。
  • エラーがある場合は、エラーメッセージが返ります。

10. API をテストする

API がデータベースをクエリできるようになったので、ローカルでテストできます。

  1. 次のコマンドを実行して、開発サーバーを起動します。

    npm run dev
  2. 新しいターミナルウィンドウで、次の cURL コマンドを実行します。YOUR_API_KEY を正しい値に置き換えてください。

    /api/allsh
    curl -H "Authorization: Bearer YOUR_API_KEY" "http://localhost:8787/api/all" --data '{"query": "SELECT title FROM posts WHERE id=?", "params":1}'
    /api/batchsh
    curl -H "Authorization: Bearer YOUR_API_KEY" "http://localhost:8787/api/batch" --data '{"batch": [ {"query": "SELECT title FROM posts WHERE id=?", "params":1},{"query": "SELECT id FROM posts"}]}'
    /api/execsh
    curl -H "Authorization: Bearer YOUR_API_KEY" "localhost:8787/api/exec" --data '{"query": "INSERT INTO posts (author, title, body, post_slug) VALUES ('\''Harshil'\'', '\''D1 HTTP API'\'', '\''Learn to create an API to query your D1 database.'\'','\''d1-http-api'\'')" }'

正しく実装されていれば、上記のコマンドは成功した結果になります。

11. API をデプロイする

期待どおりに動作するようになったので、最後の手順は Cloudflare ネットワークへのデプロイです。API のデプロイには Wrangler を使います。

  1. ローカルではなく本番で API を使うには、リモート(本番)データベースにテーブルを追加する必要があります。本番データベースにテーブルを追加するには、次のコマンドを実行します。

    npx wrangler d1 execute d1-http-example --file=./schemas/schema.sql --remote

    Cloudflare ダッシュボード > Storage & Databases > D1 でテーブルを確認できるようになります。

  2. アプリケーションを Cloudflare ネットワークへデプロイするには、次のコマンドを実行します。

    npx wrangler deploy
     ⛅️ wrangler 3.78.4 (update available 3.78.5)
    -------------------------------------------------------
    
    Total Upload: 53.00 KiB / gzip: 13.16 KiB
    Your worker has access to the following bindings:
    - D1 Databases:
      - DB: d1-http-example (DATABASE_ID)
    Uploaded d1-http (4.29 sec)
    Deployed d1-http triggers (5.57 sec)
      [DEPLOYED_APP_LINK]
    Current Version ID: [BINDING_ID]

    デプロイが成功すると、ターミナルにデプロイ済みアプリのリンク(DEPLOYED_APP_LINK)が表示されます。控えておきます。

  3. 本番で使う新しい API キーを生成します。

    openssl rand -base64 32
    [YOUR_API_KEY]
  4. wrangler secret put コマンドを実行し、デプロイ済みプロジェクトに API キーを追加します。

    npx wrangler secret put API_KEY
     Enter a secret value:

    ターミナルがシークレット値の入力を求めます。

  5. API キーの値(YOUR_API_KEY)を入力します。API キーがプロジェクトに追加されます。この値を使って、デプロイ済み API へ安全に API 呼び出しができます。

     Enter a secret value: [YOUR_API_KEY]
    🌀 Creating the secret for the Worker "d1-http"
     Success! Uploaded secret API_KEY
  6. テストするには、正しい YOUR_API_KEYDEPLOYED_APP_LINK で次の cURL コマンドを実行します。

    • シークレットの API キーとして、生成した YOUR_API_KEY を使います。
    • DEPLOYED_APP_LINK は、Cloudflare ダッシュボード > Workers & Pages > d1-http > Settings > Domains & Routes でも確認できます。
    curl -H "Authorization: Bearer YOUR_API_KEY" "https://DEPLOYED_APP_LINK/api/exec" --data '{"query": "SELECT 1"}'

まとめ

このチュートリアルでは、次を行いました。

  1. D1 データベースとやり取りする API を作成しました。
  2. この API を Workers へデプロイしました。外部アプリケーションからこの API を使い、D1 データベースに対してクエリを実行できます。このチュートリアルの完全なコードは GitHub にあります。

次のステップ

検証に Zod を使う類似の実装は、この GitHub リポジトリ で確認できます。D1 データベース向けの OpenAPI 準拠 API を構築する場合は、Cloudflare Workers OpenAPI 3.1 テンプレート を使ってください。

役に立ちましたか?