コンテンツにスキップ

Cloudflare Workersを使用してPostgreSQLデータベースに接続する

Last reviewed: about 1 month ago

このチュートリアルでは、Cloudflare Workersアプリケーションを作成し、TCPソケットHyperdriveを使用してPostgreSQLデータベースに接続する方法を学びます。このチュートリアルで作成するWorkersアプリケーションは、PostgreSQL内の製品データベースと対話します。

前提条件

続行するには:

  1. まだアカウントを作成していない場合は、Cloudflareアカウントにサインアップしてください。
  2. npmをインストールします。
  3. Node.jsをインストールします。権限の問題を避け、Node.jsのバージョンを変更するために、VoltanvmのようなNodeバージョンマネージャを使用してください。Wranglerは、16.17.0以上のNodeバージョンを必要とします。
  4. PostgreSQLデータベースにアクセスできることを確認してください。

1. Workerアプリケーションを作成する

まず、create-cloudflare CLIを使用して新しいWorkerアプリケーションを作成します。これを行うには、ターミナルウィンドウを開き、次のコマンドを実行します:

Terminal window
npm create cloudflare@latest -- postgres-tutorial

これにより、create-cloudflareパッケージをインストールするように促され、セットアップウィザードが表示されます。

For setup, select the following options:

  • For What would you like to start with?, choose Hello Worldの例.
  • For Which template would you like to use?, choose Hello World Worker.
  • For Which language do you want to use?, choose TypeScript.
  • For Do you want to use git for version control?, choose Yes.
  • For Do you want to deploy your application?, choose No (we will be making some changes before deploying).

デプロイを選択すると、認証を求められ(まだログインしていない場合)、プロジェクトがデプロイされます。デプロイ後も、Workerコードを変更し、このチュートリアルの最後に再度デプロイできます。

次に、新しく作成したディレクトリに移動します:

Terminal window
cd postgres-tutorial

Node.jsの互換性を有効にする

Workerアプリケーションを作成する際に、PostgreSQLデータベースに接続するためにライブラリを使用する必要があるため、wrangler.tomlに”nodejs_compat_v2”互換性フラグを含めてNode.js APIを有効にします

wrangler.toml
compatibility_flags = ["nodejs_compat_v2"]

2. PostgreSQL接続ライブラリを追加する

PostgreSQLデータベースに接続するには、postgresライブラリが必要です。Workerアプリケーションディレクトリで、次のコマンドを実行してライブラリをインストールします:

Terminal window
npm install postgres

postgresPostgres.js)のバージョンが3.4.4以上であることを確認してください。Postgres.jsは、PagesとWorkersの両方で互換性があります。

3. PostgreSQLデータベースへの接続を構成する

PostgreSQLデータベースに接続するための2つの方法のいずれかを選択します:

  1. 接続文字列を使用する
  2. 明示的なパラメータを設定する

接続文字列を使用する

接続文字列には、データベースに接続するために必要なすべての情報が含まれています。これは、次の情報を含むURLです:

postgresql://username:password@host:port/database

usernamepasswordhostport、およびdatabaseを、PostgreSQLデータベースに適した値に置き換えます。

接続文字列をシークレットとして設定し、プレーンテキストとして保存されないようにします。例の変数名DB_URLを使用してwrangler secret putを実行します:

Terminal window
npx wrangler secret put DB_URL
wrangler secret put DB_URL
-------------------------------------------------------
? Enter a secret value: › ********************
Success! Uploaded secret DB_URL

.dev.varsファイルにローカルでDB_URLシークレットを設定します。これは、シークレットを使用したローカル開発に記載されています。

DB_URL="<あなたのPostgreSQL接続文字列を入力>"

明示的なパラメータを設定する

各データベースパラメータを、Cloudflareダッシュボードまたはwrangler.tomlファイルを介して環境変数として構成します。wrangler.tomlファイルの設定例を参照してください:

[vars]
DB_USERNAME = "postgres"
# プレーンテキストとして保存されないようにシークレットを作成してパスワードを設定します
DB_HOST = "ep-aged-sound-175961.us-east-2.aws.neon.tech"
DB_PORT = "5432"
DB_NAME = "productsdb"

パスワードをシークレットとして設定し、プレーンテキストとして保存されないようにします。DB_PASSWORDは、このシークレットにアクセスするための例の変数名です:

Terminal window
npx wrangler secret put DB_PASSWORD
-------------------------------------------------------
? Enter a secret value: › ********************
Success! Uploaded secret DB_PASSWORD

4. Worker内でPostgreSQLデータベースに接続する

Workerのメインファイル(例えば、worker.ts)を開き、pgライブラリからClientクラスをインポートします:

import postgres from "postgres";

fetchイベントハンドラー内で、選択した方法(接続文字列または明示的なパラメータ)を使用してPostgreSQLデータベースに接続します。

接続文字列を使用する

const sql = postgres(env.DB_URL);

明示的なパラメータを設定する

const sql = postgres({
username: env.DB_USERNAME,
password: env.DB_PASSWORD,
host: env.DB_HOST,
port: env.DB_PORT,
database: env.DB_NAME,
});

5. 製品データベースと対話する

製品データベースと対話する方法を示すために、リクエストを受信したときにproductsテーブルからデータを取得します。

worker.tsファイル内の既存のコードを次のコードに置き換えます:

import postgres from "postgres";
export default {
async fetch(request, env, ctx): Promise<Response> {
const sql = postgres(env.DB_URL);
// productsテーブルをクエリする
const result = await sql`SELECT * FROM products;`;
// 結果をJSONとして返す
const resp = new Response(JSON.stringify(result), {
headers: { "Content-Type": "application/json" },
});
return resp;
},
} satisfies ExportedHandler<Env>;

このコードは、Workerアプリケーション内でPostgreSQLデータベースへの接続を確立し、productsテーブルをクエリし、結果をJSONレスポンスとして返します。

6. Workerをデプロイする

次のコマンドを実行してWorkerをデプロイします:

Terminal window
npx wrangler deploy

あなたのアプリケーションは現在ライブで、<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.devでアクセス可能です。

デプロイ後、Cloudflare Workerを使用してPostgreSQL製品データベースと対話できます。WorkerのURLにリクエストが行われるたびに、productsテーブルからデータを取得し、JSONレスポンスとして返します。必要に応じてクエリを変更して、製品データベースから必要なデータを取得できます。

7. 製品データベースに新しい行を挿入する

productsテーブルに新しい行を挿入するには、POSTリクエストを処理する新しいAPIエンドポイントをWorkerに作成します。POSTリクエストがJSONペイロードと共に受信されると、Workerは提供されたデータを使用してproductsテーブルに新しい行を挿入します。

productsテーブルには、idnamedescription、およびpriceの列があります。

次のコードスニペットを、既存のクエリコードの前にworker.tsファイルのfetchイベントハンドラー内に追加します:

import postgres from "postgres";
export default {
async fetch(request, env, ctx): Promise<Response> {
const sql = postgres(env.DB_URL);
const url = new URL(request.url);
if (request.method === "POST" && url.pathname === "/products") {
// リクエストのJSONペイロードを解析する
const productData = await request.json();
// データベースに新しい製品を挿入する
const values = {
name: productData.name,
description: productData.description,
price: productData.price,
};
const insertResult = await sql`
INSERT INTO products ${sql(values)}
RETURNING *
`;
// 挿入された行をJSONとして返す
const insertResp = new Response(JSON.stringify(insertResult), {
headers: { "Content-Type": "application/json" },
});
// クライアントをクリーンアップする
return insertResp;
}
// productsテーブルをクエリする
const result = await sql`SELECT * FROM products;`;
// 結果をJSONとして返す
const resp = new Response(JSON.stringify(result), {
headers: { "Content-Type": "application/json" },
});
return resp;
},
} satisfies ExportedHandler<Env>;

このコードスニペットは次のことを行います:

  1. リクエストがPOSTリクエストであり、URLパスが/productsであるかどうかを確認します。
  2. リクエストからJSONペイロードを解析します。
  3. 提供された製品データを使用してINSERT SQLクエリを構築します。
  4. クエリを実行し、新しい行をproductsテーブルに挿入します。
  5. 挿入された行をJSONレスポンスとして返します。

これで、WorkerのURLに/productsパスと新しい製品データを含むJSONペイロードでPOSTリクエストを送信すると、Workerは提供されたデータを使用してproductsテーブルに新しい行を挿入します。/へのリクエストが行われると、Workerはデータベース内のすべての製品を返します。

これらの変更を行った後、次のコマンドを実行してWorkerを再度デプロイします:

Terminal window
npx wrangler deploy

これで、Cloudflare Workerを使用してproductsテーブルに新しい行を挿入できるようになりました。この機能をテストするには、WorkerのURLに/productsパスを持つPOSTリクエストを送信し、新しい製品データを含むJSONペイロードを送信します:

{
"name": "サンプル製品",
"description": "これはサンプル製品です",
"price": 19.99
}

PostgreSQLデータベースに接続し、データの取得と新しい行の挿入を処理するCloudflare Workerを正常に作成しました。

8. Hyperdriveを使用してクエリを加速する

PostgreSQLデータベースの接続文字列を使用してHyperdrive構成を作成します。

Terminal window
npx wrangler hyperdrive create <HYPERDRIVE_CONFIGの名前> --connection-string="postgres://user:password@HOSTNAME_OR_IP_ADDRESS:PORT/database_name"

明示的なパラメータを使用することもできます。これは、wranglerのHyperdriveに関するドキュメントを参照してください。

このコマンドは、Hyperdrive バインディングに使用されるHyperdrive構成のidを出力します。wrangler.tomlファイルにidを指定してバインディングを設定します。

name = "hyperdrive-example"
main = "src/index.ts"
compatibility_date = "2024-08-21"
compatibility_flags = ["nodejs_compat"]
# 上記の`wrangler hyperdrive create <HYPERDRIVE_CONFIGの名前> --connection-string=[...]`の出力から貼り付けました。
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<作成したHYPERDRIVE構成のID>"

次のコマンドを使用してHyperdriveバインディングの型を作成します:

Terminal window
npx wrangler types

Workerコード内の既存の接続文字列をHyperdrive接続文字列に置き換えます。

export default {
async fetch(request, env, ctx): Promise<Response> {
const sql = postgres(env.HYPERDRIVE.connectionString)
const url = new URL(request.url);
// 残りのルートとデータベースクエリ
},
} satisfies ExportedHandler<Env>;

9. Workerを再デプロイする

次のコマンドを実行してWorkerをデプロイします:

Terminal window
npx wrangler deploy

あなたのWorkerアプリケーションは現在ライブで、Hyperdriveを使用して<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.devでアクセス可能です。Hyperdriveは、接続をプールし、リクエストを世界中でキャッシュすることによってデータベースクエリを加速します。

次のステップ

データベースとWorkersを使用してさらに構築するには、チュートリアルを参照し、データベースのドキュメントを探索してください。

質問がある場合、支援が必要な場合、またはプロジェクトを共有したい場合は、Cloudflare Developerコミュニティに参加して、Discordで他の開発者やCloudflareチームとつながりましょう。