跳转到内容
搜索文档

使用 Workers 连接并查询 Turso 数据库

最后更新 查看 MarkdownAgent 设置

本教程将指导你如何使用 Cloudflare Workers 和 Turso(基于 libSQL 的边缘托管分布式数据库)构建全球分布式应用。通过使用 Workers 和 Turso,你可以创建靠近终端用户的应用,而无需在数十或数百个区域维护或运营基础设施。

前置条件

继续本教程之前,你应已:

安装 Turso CLI

你需要 Turso CLI 来创建和填充数据库。在终端中运行以下两个命令之一来安装 Turso CLI:

# On macOS or Linux with Homebrew
brew install chiselstrike/tap/turso

# Manual scripted installation
curl -sSfL <https://get.tur.so/install.sh> | bash

安装 Turso CLI 后,验证 CLI 是否在 shell 路径中:

turso --version
# This should output your current Turso CLI version (your installed version may be higher):
turso version v0.51.0

创建并填充数据库

创建第一个 Turso 数据库之前,需要使用 GitHub 账户登录 CLI,运行:

turso auth login

Waiting for authentication...
  Success! Logged in as <your GitHub username>

turso auth login 将打开浏览器窗口并要求你登录 GitHub 账户(若尚未登录)。首次执行此操作时,你需要授予 Turso 应用使用账户的权限。选择 Approve(批准) 以授予 Turso 所需权限。

身份验证完成后,可通过运行 turso db create <DATABASE_NAME> 创建数据库。Turso 会自动选择离你最近的位置。

turso db create my-db
# Example:
[===>                ]
Creating database my-db in Los Angeles, California (US) (lax)
# Once succeeded:
Created database my-db in Los Angeles, California (US) (lax) in 34 seconds.

创建第一个数据库后,你现在可以直接连接并对其执行 SQL:

turso db shell my-db

要开始使用数据库,创建并定义第一个表的 schema。在本示例中,你将创建 example_users 表,包含一列:email(类型为 text),然后填入一个邮箱地址。

在刚打开的 shell 中,粘贴以下 SQL:

create table example_users (email text);
insert into example_users values ('foo@bar.com');

若 SQL 语句执行成功,将无输出。注意末尾的分号(;)是终止每条 SQL 语句所必需的。

输入 .quit 退出 shell。

使用 Wrangler 创建 Workers 项目

Workers 命令行界面 Wrangler 允许你创建、本地开发和部署 Workers 项目。

要创建新的 Workers 项目(名为 worker-turso-ts),运行:

npm create cloudflare@latest -- worker-turso-ts

进行设置时,请选择以下选项:

  • 对于 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(部署前我们还会做一些修改)。

要开始开发 Worker,请 cd 进入新项目目录:

cd worker-turso-ts

在项目目录中,你现在拥有以下文件:

  • wrangler.json / wrangler.tomlWrangler 配置文件
  • src/index.ts:用 TypeScript 编写的最小 Hello World Worker
  • package.json:最小的 Node 依赖配置文件。
  • tsconfig.json:包含 Workers 类型的 TypeScript 配置。仅在指定时生成。

对于本教程,只有 Wrangler 配置文件src/index.ts 文件相关。你无需编辑其他文件,应保持原样。

为 Turso 数据库配置 Worker

Turso 客户端库需要两项信息来建立连接:

  1. LIBSQL_DB_URL - Turso 数据库的连接字符串。
  2. LIBSQL_DB_AUTH_TOKEN - Turso 数据库的身份验证令牌。应保密,不得提交到源代码。

要获取数据库 URL,运行以下 Turso CLI 命令并复制结果:

turso db show my-db --url
libsql://my-db-<your-github-username>.turso.io

在编辑器中打开 Wrangler 配置文件,在文件底部创建新的 [vars] 部分,表示项目的环境变量

{
	"vars": {
		"LIBSQL_DB_URL": "paste-your-url-here"
	}
}
[vars]
LIBSQL_DB_URL = "paste-your-url-here"

保存对 Wrangler 配置文件的更改。

接下来,为 Worker 创建长期身份验证令牌以便连接数据库。运行以下 Turso CLI 命令,将输出复制到剪贴板:

turso db tokens create my-db -e none
# Will output a long text string (an encoded JSON Web Token)

为保持此令牌保密:

  1. 你将创建 .dev.vars 文件用于本地开发。请勿将此文件提交到源代码管理。若使用 Git,应将 .dev.vars 添加到 .gitignore 文件。

首先,创建名为 .dev.vars 的新文件,结构如下。在引号中粘贴身份验证令牌:

LIBSQL_DB_AUTH_TOKEN="<YOUR_AUTH_TOKEN>"

保存对 .dev.vars 的更改。接下来,将身份验证令牌存储为生产 Worker 引用的 secret。运行以下 wrangler secret 命令,使用你的令牌创建 Secret:

# Ensure you specify the secret name exactly: your Worker will need to reference it later.
npx wrangler secret put LIBSQL_DB_AUTH_TOKEN
? Enter a secret value: › <paste your token here>

在键盘上按 <Enter> 保存令牌为 secret。LIBSQL_DB_URLLIBSQL_DB_AUTH_TOKEN 都将在运行时可用于 Worker 的环境。

安装额外库

安装 Turso 客户端库和路由器:

npm i @libsql/client itty-router

@libsql/client 库允许你查询 Turso 数据库。itty-router 库是一个轻量级路由器,用于帮助处理传入 worker 的请求。

编写 Worker

你现在将编写一个 Worker,它将:

  1. 处理 HTTP 请求。
  2. 将请求路由到特定处理程序,以列出数据库中的所有用户或添加新用户。
  3. 返回结果和/或成功状态。

打开 src/index.ts 并删除现有模板。完全按原样复制以下代码并粘贴到文件中:

import { Client as LibsqlClient, createClient } from "@libsql/client/web";
import { Router, RouterType } from "itty-router";

export interface Env {
	// The environment variable containing your the URL for your Turso database.
	LIBSQL_DB_URL?: string;
	// The Secret that contains the authentication token for your Turso database.
	LIBSQL_DB_AUTH_TOKEN?: string;

	// These objects are created before first use, then stashed here
	// for future use
	router?: RouterType;
}

export default {
	async fetch(request, env): Promise<Response> {
		if (env.router === undefined) {
			env.router = buildRouter(env);
		}

		return env.router.fetch(request);
	},
} satisfies ExportedHandler<Env>;

function buildLibsqlClient(env: Env): LibsqlClient {
	const url = env.LIBSQL_DB_URL?.trim();
	if (url === undefined) {
		throw new Error("LIBSQL_DB_URL env var is not defined");
	}

	const authToken = env.LIBSQL_DB_AUTH_TOKEN?.trim();
	if (authToken === undefined) {
		throw new Error("LIBSQL_DB_AUTH_TOKEN env var is not defined");
	}

	return createClient({ url, authToken });
}

function buildRouter(env: Env): RouterType {
	const router = Router();

	router.get("/users", async () => {
		const client = buildLibsqlClient(env);
		const rs = await client.execute("select * from example_users");
		return Response.json(rs);
	});

	router.get("/add-user", async (request) => {
		const client = buildLibsqlClient(env);
		const email = request.query.email;
		if (email === undefined) {
			return new Response("Missing email", { status: 400 });
		}
		if (typeof email !== "string") {
			return new Response("email must be a single string", { status: 400 });
		}
		if (email.length === 0) {
			return new Response("email length must be > 0", { status: 400 });
		}

		try {
			await client.execute({
				sql: "insert into example_users values (?)",
				args: [email],
			});
		} catch (e) {
			console.error(e);
			return new Response("database insert failed");
		}

		return new Response("Added");
	});

	router.all("*", () => new Response("Not Found.", { status: 404 }));

	return router;
}

保存对 src/index.ts 文件的更改。

注意:

  • 在使用 Cloudflare Workers 时,libSQL 客户端库导入 '@libsql/client/web' 必须完全按所示导入。非 web 导入在 Workers 环境中无法工作。
  • Env 接口包含你先前定义的环境变量和 secret。
  • Env 接口还缓存 libSQL 客户端对象和路由器,它们在 Worker 的第一次请求时创建。
  • /users 路由从你在 Turso shell 中创建的 example_users 表获取所有行。它将 ResultSet 对象直接序列化为 JSON 返回给调用者。
  • /add-user 路由使用查询字符串中提供的值插入新行。

环境配置完成且代码就绪后,你将在部署前本地测试 Worker。

使用 Wrangler 本地运行 Worker

要在本地运行 Worker 实例(完全在你的机器上),运行以下命令:

npx wrangler dev

你应该能看到类似以下的输出:

Your worker has access to the following bindings:
- Vars:
  - LIBSQL_DB_URL: "your-url"
⎔ Starting a local server...
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ [b] open a browser, [d] open Devtools, [l] turn off local mode, [c] clear console, [x] to exit                                                                  	│
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Debugger listening on ws://127.0.0.1:61918/1064babd-bc9d-4bed-b171-b35dab3b7680
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
[mf:inf] Worker reloaded! (40.25KiB)
[mf:inf] Listening on 0.0.0.0:8787
[mf:inf] - http://127.0.0.1:8787
[mf:inf] - http://192.168.1.136:8787
[mf:inf] Updated `Request.cf` object cache!

localhost 地址——包含 127.0.0.1 的那个——是在你机器上本地运行的 Web 服务器。

连接它并通过在浏览器中访问 /users 路由验证 Worker 返回创建 example_users 表时插入的邮箱地址:http://127.0.0.1:8787/users

你应该看到类似以下的 JSON,包含 example_users 表中的数据:

{
	"columns": ["email"],
	"rows": [{ "email": "foo@bar.com" }],
	"rowsAffected": 0
}

测试 /add-users 路由并传递要插入的邮箱地址:http://127.0.0.1:8787/add-user?email=test@test.com

你应该看到文本 "Added"。若再次加载带有 /users 路由的第一个 URL(http://127.0.0.1:8787/users),将显示新添加的行。你可以重复此操作任意次数。注意,由于设计原因,应用不会阻止你添加重复的邮箱地址。

在启动 Wrangler 的 shell 中输入 q 退出 Wrangler。

部署到 Cloudflare

验证 Worker 可以连接 Turso 数据库后,部署 Worker。运行以下 Wrangler 命令将 Worker 部署到 Cloudflare 全球网络:

npx wrangler deploy

首次运行此命令时,将启动浏览器,要求你使用 Cloudflare 账户登录并授予 Wrangler 权限。

deploy 命令将输出以下内容:

Your worker has access to the following bindings:
- Vars:
  - LIBSQL_DB_URL: "your-url"
...
Published worker-turso-ts (0.19 sec)
  https://worker-turso-ts.<your-Workers-subdomain>.workers.dev
Current Deployment ID: f9e6b48f-5aac-40bd-8f44-8a40be2212ff

你现在已部署一个可以连接 Turso 数据库、查询并插入新数据的 Worker。

可选:清理

要清理本教程中创建的资源:

  • 若不想保留此 Worker,运行 npx wrangler delete worker-turso-ts 删除已部署的 Worker。
  • 你也可以通过 turso db destroy my-db 删除 Turso 数据库。

相关资源

这篇文档对您有帮助吗?