Cloudflare Workersを使用してPostgreSQLデータベースに接続する
このチュートリアルでは、Cloudflare Workersアプリケーションを作成し、TCPソケットとHyperdriveを使用してPostgreSQLデータベースに接続する方法を学びます。このチュートリアルで作成するWorkersアプリケーションは、PostgreSQL内の製品データベースと対話します。
続行するには:
- まだアカウントを作成していない場合は、Cloudflareアカウント ↗にサインアップしてください。
npm↗をインストールします。Node.js↗をインストールします。権限の問題を避け、Node.jsのバージョンを変更するために、Volta ↗やnvm ↗のようなNodeバージョンマネージャを使用してください。Wranglerは、16.17.0以上のNodeバージョンを必要とします。- PostgreSQLデータベースにアクセスできることを確認してください。
まず、create-cloudflare CLI ↗を使用して新しいWorkerアプリケーションを作成します。これを行うには、ターミナルウィンドウを開き、次のコマンドを実行します:
npm create cloudflare@latest -- postgres-tutorialyarn create cloudflare@latest postgres-tutorialpnpm 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コードを変更し、このチュートリアルの最後に再度デプロイできます。
次に、新しく作成したディレクトリに移動します:
cd postgres-tutorialWorkerアプリケーションを作成する際に、PostgreSQLデータベースに接続するためにライブラリを使用する必要があるため、wrangler.tomlに”nodejs_compat_v2”互換性フラグを含めてNode.js APIを有効にします。
compatibility_flags = ["nodejs_compat_v2"]PostgreSQLデータベースに接続するには、postgresライブラリが必要です。Workerアプリケーションディレクトリで、次のコマンドを実行してライブラリをインストールします:
npm install postgrespostgres(Postgres.js)のバージョンが3.4.4以上であることを確認してください。Postgres.jsは、PagesとWorkersの両方で互換性があります。
PostgreSQLデータベースに接続するための2つの方法のいずれかを選択します:
接続文字列には、データベースに接続するために必要なすべての情報が含まれています。これは、次の情報を含むURLです:
postgresql://username:password@host:port/databaseusername、password、host、port、およびdatabaseを、PostgreSQLデータベースに適した値に置き換えます。
接続文字列をシークレットとして設定し、プレーンテキストとして保存されないようにします。例の変数名DB_URLを使用してwrangler secret putを実行します:
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は、このシークレットにアクセスするための例の変数名です:
npx wrangler secret put DB_PASSWORD-------------------------------------------------------? Enter a secret value: › ********************✨ Success! Uploaded secret DB_PASSWORDWorkerのメインファイル(例えば、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,});製品データベースと対話する方法を示すために、リクエストを受信したときに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レスポンスとして返します。
次のコマンドを実行してWorkerをデプロイします:
npx wrangler deployあなたのアプリケーションは現在ライブで、<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.devでアクセス可能です。
デプロイ後、Cloudflare Workerを使用してPostgreSQL製品データベースと対話できます。WorkerのURLにリクエストが行われるたびに、productsテーブルからデータを取得し、JSONレスポンスとして返します。必要に応じてクエリを変更して、製品データベースから必要なデータを取得できます。
productsテーブルに新しい行を挿入するには、POSTリクエストを処理する新しいAPIエンドポイントをWorkerに作成します。POSTリクエストがJSONペイロードと共に受信されると、Workerは提供されたデータを使用してproductsテーブルに新しい行を挿入します。
productsテーブルには、id、name、description、および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>;このコードスニペットは次のことを行います:
- リクエストが
POSTリクエストであり、URLパスが/productsであるかどうかを確認します。 - リクエストからJSONペイロードを解析します。
- 提供された製品データを使用して
INSERTSQLクエリを構築します。 - クエリを実行し、新しい行を
productsテーブルに挿入します。 - 挿入された行をJSONレスポンスとして返します。
これで、WorkerのURLに/productsパスと新しい製品データを含むJSONペイロードでPOSTリクエストを送信すると、Workerは提供されたデータを使用してproductsテーブルに新しい行を挿入します。/へのリクエストが行われると、Workerはデータベース内のすべての製品を返します。
これらの変更を行った後、次のコマンドを実行してWorkerを再度デプロイします:
npx wrangler deployこれで、Cloudflare Workerを使用してproductsテーブルに新しい行を挿入できるようになりました。この機能をテストするには、WorkerのURLに/productsパスを持つPOSTリクエストを送信し、新しい製品データを含むJSONペイロードを送信します:
{ "name": "サンプル製品", "description": "これはサンプル製品です", "price": 19.99}PostgreSQLデータベースに接続し、データの取得と新しい行の挿入を処理するCloudflare Workerを正常に作成しました。
PostgreSQLデータベースの接続文字列を使用してHyperdrive構成を作成します。
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バインディングの型を作成します:
npx wrangler typesWorkerコード内の既存の接続文字列を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>;次のコマンドを実行してWorkerをデプロイします:
npx wrangler deployあなたのWorkerアプリケーションは現在ライブで、Hyperdriveを使用して<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.devでアクセス可能です。Hyperdriveは、接続をプールし、リクエストを世界中でキャッシュすることによってデータベースクエリを加速します。
データベースとWorkersを使用してさらに構築するには、チュートリアルを参照し、データベースのドキュメントを探索してください。
質問がある場合、支援が必要な場合、またはプロジェクトを共有したい場合は、Cloudflare Developerコミュニティに参加して、Discord ↗で他の開発者やCloudflareチームとつながりましょう。