跳转到内容
搜索文档

使用代理 Worker 构建访问 D1 的 API

最后更新 查看 MarkdownAgent 设置

在本教程中,您将学习如何创建 API,使您能够安全地对 D1 数据库运行查询。

如果您想在 Worker 或 Pages 项目之外访问 D1 数据库、自定义访问控制 和/或 限制可查询的表,这很有用。

D1 内置的 REST API 最适合管理用途,因为适用全局 Cloudflare API 速率限制

要在 Worker 项目之外访问 D1 数据库,您需要使用 Worker 创建 API。然后您的应用可以安全地与此 API 交互以运行 D1 查询。

前提条件

  1. 注册 Cloudflare 账户
  2. 安装 Node.js
  3. 拥有现有 D1 数据库。请参阅 D1 快速入门教程

Node.js version manager

使用像 Voltanvm 这样的 Node 版本管理器,以避免权限问题并方便更改 Node.js 版本。本指南稍后讨论的 Wrangler 要求 Node 版本为 16.17.0 或更高。

1. 创建新项目

创建新 Worker 以创建和部署 API。

  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

在本教程中,您将使用 Hono(Express.js 风格框架)构建 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 应用程序,并配置以下中间件:

  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
    
    // 将此代码粘贴在 src/index.ts 文件的末尾
    
    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,请打开第二个终端。

  4. 在第二个终端中,执行以下 cURL 命令。将 YOUR_API_KEY 替换为您在 .dev.vars 文件中设置的值。

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

    您应该得到以下输出:

    /api/all endpoint
  5. 在第一个终端中按 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" # 即在您的 Worker 中可通过 env.DB 使用
    database_name = "d1-http-example"
    database_id = "1234567890"

记下显示的 database_namedatabase_id。您将通过创建绑定(binding)来引用数据库。

7. 添加绑定

  1. 在您的 d1-http 文件夹中,打开 Wrangler 配置文件。

  2. 在文件中添加以下绑定。确保 database_namedatabase_id 正确无误。

    {
      "d1_databases": [
        {
          "binding": "DB", // 即在您的 Worker 中可通过 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 文件中,通过添加 DB: D1Database 来更新 Bindings 类型。

    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 您的 D1 数据库.','d1-http-api');

    该代码会删除名为 posts 的现有表(如果存在),然后创建一个具有 idauthortitlebodypost_slug 字段的新表 posts。接着使用 INSERT 语句填充表。

  3. 在终端中,执行以下命令以创建此表:

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

成功执行后,一个新表将被添加到您的数据库中。

9. 查询数据库

您的应用现在可以访问 D1 数据库。在此步骤中,您将更新 API 端点以查询数据库并返回结果。

  1. In your src/index.ts file, update the code as follow.

    src/index.tsts
    // 更新 API routes
    
    /**
    * 执行 stmt.run() 方法。
    * 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);
    	}
    });
    
    /**
    * 执行 db.exec() 方法。
    * 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);
    	}
    });
    
    /**
    * 执行 db.batch() 方法。
    * 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 您的 D1 数据库.'\'','\''d1-http-api'\'')" }'

如果一切实现正确,上述命令应该会产生成功的输出。

11. 部署 API

一切按预期工作后,最后一步是将其部署到 Cloudflare 网络。您将使用 Wrangler 部署 API。

  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 命令。

    • 使用您生成的 YOUR_API_KEY 作为机密 API 密钥。
    • 您也可以在 Cloudflare 仪表板 > Workers & Pages > d1-http > Settings(设置) > Domains & Routes(域与路由) 中找到您的 DEPLOYED_APP_LINK
    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 上找到。

后续步骤

您可以在 此 GitHub 仓库 中查看使用 Zod 进行验证的类似实现。如果您想为您的 D1 数据库构建符合 OpenAPI 标准的 API,您应该使用 Cloudflare Workers OpenAPI 3.1 模板

这篇文档对您有帮助吗?