使用 Cloudflare Workers 连接 PostgreSQL 数据库教程

70 min read

使用 Cloudflare Workers 连接 PostgreSQL 数据库教程

在本教程中,您将学习如何创建 Cloudflare Workers 应用程序并使用 TCP 套接字将其连接到 PostgreSQL 数据库。您在本教程中创建的 Workers 应用程序将与 PostgreSQL 中的产品数据库交互。

先决条件

  • 注册 Cloudflare 账户。
  • 安装 npm。
  • 安装 Node.js(使用 Volta 或 nvm 等节点版本管理器以避免权限问题和更改 Node.js 版本)。Wrangler 需要 Node.js 16.17.0 或更高版本。
  • 确保您可以访问 PostgreSQL 数据库。

1. 创建一个 Worker 应用程序

首先,使用 create-cloudflare CLI 创建一个新的 Worker 应用程序。打开终端窗口并运行以下命令:

npm create cloudflare@latest

按照提示完成安装和设置:

  • 为新的 Worker 应用程序命名。
  • 选择 "Hello World" Worker 作为应用程序类型。
  • 选择 Yes 使用 TypeScript。
  • 选择 No 部署应用程序。

2. 启用 Node.js 兼容性

wrangler.toml 文件中添加 node_compat 关键字以启用 Node.js API 的 polyfills:

node_compat = true

3. 添加 PostgreSQL 连接库

在 Worker 应用程序目录下,运行以下命令安装 pg 库:

npm install pg

确保使用的是 pg (node-postgres) 8.11.0 或更高版本。

4. 配置与 PostgreSQL 数据库的连接

您可以选择使用连接字符串或显式参数来连接 PostgreSQL 数据库。

使用连接字符串

将连接字符串设为密文以避免明文存储:

npx wrangler secret put DB_URL
设置显式参数

通过 Cloudflare 面板或在 wrangler.toml 文件中将每个数据库参数配置为环境变量:

[vars]
DB_USERNAME = "postgres"
DB_HOST = "your_host"
DB_PORT = "5432"
DB_NAME = "productsdb"

将密码设置为密文:

npx wrangler secret put DB_PASSWORD

5. 在 Worker 中连接 PostgreSQL 数据库

worker.ts 文件中导入 pg 库的 Client 类,并使用连接字符串或显式参数连接数据库。

使用连接字符串
import { Client } from "pg";

export default {
  async fetch(request, env, ctx): Promise<Response> {
    const client = new Client(env.DB_URL);
    await client.connect();

    // 查询产品表
    const result = await client.query("SELECT * FROM products");

    // 以 JSON 格式返回结果
    const resp = new Response(JSON.stringify(result.rows), {
      headers: { "Content-Type": "application/json" },
    });

    // 清理客户端
    ctx.waitUntil(client.end());
    return resp;
  },
} satisfies ExportedHandler<Env>;
设置显式参数
import { Client } from "pg";

export default {
  async fetch(request, env, ctx): Promise<Response> {
    const client = new Client({
      user: env.DB_USERNAME,
      password: env.DB_PASSWORD,
      host: env.DB_HOST,
      port: env.DB_PORT,
      database: env.DB_NAME
    });
    await client.connect();

    // 查询产品表
    const result = await client.query("SELECT * FROM products");

    // 以 JSON 格式返回结果
    const resp = new Response(JSON.stringify(result.rows), {
      headers: { "Content-Type": "application/json" },
    });

    // 清理客户端
    ctx.waitUntil(client.end());
    return resp;
  },
} satisfies ExportedHandler<Env>;

6. 部署您的 Worker

运行以下命令部署 Worker:

npx wrangler deploy

您的应用现已上线,并可通过 <YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev 访问。

7. 向产品数据库中插入新行

worker.ts 文件的 fetch 事件处理程序中添加以下代码片段,处理 POST 请求以插入新行:

const url = new URL(request.url);
if (request.method === "POST" && url.pathname === "/products") {
  const productData = await request.json();
  const insertQuery = `
    INSERT INTO products (name, description, price)
    VALUES ($1, $2, $3)
    RETURNING *
  `;
  const values = [productData.name, productData.description, productData.price];
  const insertResult = await client.query(insertQuery, values);

  const insertResp = new Response(JSON.stringify(insertResult.rows[0]), {
    headers: { "Content-Type": "application/json" },
  });

  ctx.waitUntil(client.end());
  return insertResp;
} else if (request.method === "GET" && url.pathname === "/products") {
  const result = await client.query("SELECT * FROM products");
  const resp = new Response(JSON.stringify(result.rows), {
    headers: { "Content-Type": "application/json" },
  });
  ctx.waitUntil(client.end());
  return resp;
}

再次运行 npx wrangler deploy 部署 Worker。现在,您可以使用 Cloudflare Worker 向 products 表中插入新行。