在 Cloudflare Worker 中通过 Supabase JS 查询 Supabase 数据
2026/9/7 5:58:40 网站建设 项目流程

在 Cloudflare Worker 中通过 Supabase JS 查询 Supabase 数据

【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabase

Supabase 提供的是基于 Postgres 的完整后端平台,而 Cloudflare Workers 是运行在全球边缘节点的无服务器运行时。这篇实战指南以仓库中的 examples/with-cloudflare-workers 示例为蓝本,完整演示了如何在 Cloudflare Worker 中安装并初始化@supabase/supabase-js客户端,把项目 URL 与发布密钥通过wrangler secret安全注入 Worker,然后执行articles表查询并以application/json响应返回给浏览器。读完本文,你将掌握一套可复制、可运行的“边缘端直连 Supabase”的最小实现,并能看懂仓库中完整可运行的 src/index.js 源码。

场景概述:为什么要在边缘端查询 Supabase

Supabase JS(即@supabase/supabase-js)是一个 NPM 包,它为 JavaScript / TypeScript 应用访问 Supabase 项目提供了简单统一的接口。它支持三种典型能力:

  • 查询与变更数据:通过对象关系映射(ORM)风格语法读写 Postgres 表中的数据;
  • 实时订阅:监听数据库变更并推送实时事件(本文不展开);
  • 服务端或客户端运行:既可在浏览器中运行,也可运行在 Node.js、Deno、Bun 以及 Cloudflare Workers 等运行时。

Cloudflare Worker 与 Supabase 的组合价值在于:Worker 在离用户最近的边缘节点执行,开发者可以在请求到达源站之前完成轻量数据聚合、权限校验或响应加速。本文对应的示例正是把“读取文章列表并返回 JSON”这一任务整体下沉到 Worker 完成。

在仓库中,examples/with-cloudflare-workers 是一个自包含的最小示例目录,完整结构如下:

examples/with-cloudflare-workers/ ├── src/ │ └── index.js # Worker 入口:创建 Supabase 客户端并查询数据 ├── package.json # 依赖与脚本(wrangler、@supabase/supabase-js) ├── wrangler.toml # Cloudflare Worker 配置 └── README.md # 教程说明

准备工作:获取项目 URL 与访问密钥

在使用 Supabase JS 之前,需要两个来自 Supabase 项目的信息:

  • 项目 URL:形如https://<project-ref>.supabase.co的 RESTful 端点地址;
  • 访问密钥:用于通过网关鉴权。该密钥可在 Supabase Dashboard 的Settings > API中获取。

原文教程里该密钥被称作Anon Key。需要说明的是,随着生态对密钥语义的澄清,当前仓库内多个示例已将代码与文档中的命名统一为publishable key(可发布密钥),例如 src/index.js 中的环境变量名是SUPABASE_PUBLISHABLE_KEY,nextjs-full 示例也使用NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY。本质上它就是createClient的第二个参数,用于网关层鉴权。

这类密钥在客户端环境暴露是预期行为,因此使用时应配合数据库行级安全策略(RLS)约束可读数据范围,不要把service_role这类高权限密钥放进边缘 Worker。

第一步:安装 Supabase JS

在 Worker 项目目录内,用 npm 安装官方客户端:

npm i @supabase/supabase-js

仓库中的 package.json 给出了完整依赖声明,与本示例一致:

{ "name": "supabase-at-the-edge", "devDependencies": { "wrangler": "2.20.1" }, "dependencies": { "@supabase/supabase-js": "^2" }, "scripts": { "start": "wrangler dev", "deploy": "wrangler publish" } }

可以看到,示例同时声明了两个运行时层面的依赖:应用依赖@supabase/supabase-js的 v2 大版本;开发依赖wranglerCLI(此示例锁定在2.20.1),用于本地开发、密钥管理与发布。npm scripts 中预置了start(等价于wrangler dev)与deploy(等价于wrangler publish)两条常用命令。

第二步:编写 Worker 入口并查询数据

示例的核心逻辑集中在 src/index.js,全文不足 20 行,逐段拆解如下。

首先导入客户端工厂函数,并导出一个默认对象。Cloudflare Worker 的模块化语法约定:默认导出的对象需要暴露一个fetch方法,作为请求的入口处理器:

import { createClient } from '@supabase/supabase-js' export default { async fetch(request, { SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY }) { const supabase = createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY) const { data } = await supabase.from('articles').select('*') return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json', }, }) }, }

这里蕴含三个关键知识点:

  1. 环境变量的注入方式fetch的第二个参数是env绑定对象,其中包含 Worker 可访问的全部环境变量与绑定资源。示例通过解构语法直接取出SUPABASE_URLSUPABASE_PUBLISHABLE_KEY,它们由 Cloudflare 侧以密钥(secret)形式注入,详见下文“密钥管理”一节。

  2. 客户端初始化createClient(projectUrl, anonKey)是 Supabase JS 的标准初始化签名。第一个参数是项目 REST 端点,第二个参数是密钥。初始化完成后即可使用 ORM 风格的查询语法:

    const { data } = await supabase.from('articles').select('*')

    该调用等价于从 Postgres 的articles表读取全量记录,返回结果按解构约定放入data字段。仓库中其它示例(如 expo-social-auth 的客户端封装)采用完全相同的createClient初始化模式,验证了这套 API 是跨端一致的。

  3. 返回 JSON 响应supabase-js返回的是 JavaScript 对象,而网络响应体要求字符串或字节流。因此需要先用JSON.stringify(data)序列化,随后在Response中设置Content-Type: application/json请求头,通知浏览器按 JSON 解析响应内容。这是 Worker 返回结构化数据时的标准做法。

第三步:配置 wrangler.toml

仓库中的 wrangler.toml 内容如下:

name = "supabase-at-the-edge" main = "src/index.js" compatibility_date = "2022-07-26"

三个字段的含义分别是:

  • name:Worker 在 Cloudflare 上的部署名称;
  • main:入口模块文件,即上文中的src/index.js
  • compatibility_date:指定 Workers 运行时的兼容性日期,锁定某版本的运行时行为,避免将来行为变更破坏现有代码。

第四步:本地开发运行

编辑完成后,先通过 wrangler 的本地开发服务器验证代码行为:

npx wrangler dev

wrangler dev会在本机启动一个模拟 Workers 运行时的开发服务器,绑定wrangler.toml中的入口文件。本地调试时需要注意:正式密钥以 Cloudflare 账户级 secret 形式存储,默认不会出现在本地环境。实践中可参考 wrangler 对本地变量的支持,在开发阶段补充可用的本地配置后再行联调。

第五步:用 wrangler secret 注入密钥

正式环境中,项目 URL 与发布密钥不应硬编码进源码,而应作为secret(密钥)存储在 Cloudflare 账户中。Wrangler 提供统一命令创建密钥:

npx wrangler secret put NAME

按提示输入密钥值后,该变量会加密保存在 Cloudflare 侧,并在 Worker 运行时注入env绑定对象。为当前示例依次创建两个密钥:

添加 SUPABASE_URL 密钥

npx wrangler secret put SUPABASE_URL

添加 SUPABASE_PUBLISHABLE_KEY 密钥

npx wrangler secret put SUPABASE_PUBLISHABLE_KEY

执行上述命令时,wrangler 会要求先完成 Cloudflare 账户登录与项目选择,随后交互式地读取密钥值。密钥名必须与 src/index.js 中解构的环境变量名完全一致,Worker 才能正确取到值。仓库中的配套课程示例 with-cloudflare-workers-kv 使用完全相同的SUPABASE_URL/SUPABASE_PUBLISHABLE_KEY命名约定,说明这是一套被反复验证的既定实践。

第六步:发布部署

完成本地验证并注入密钥后,发布 Worker:

npx wrangler publish

发布后 Worker 即运行于 Cloudflare 边缘网络,任何对 Worker 路由的 HTTP 请求都会触发fetch处理器,实时查询 Supabase 的articles表并把数据以application/json响应返回。仓库 package.json 中的deploy脚本封装的就是这条命令。

完整调用链小结

把整个请求生命周期串起来看:

  1. 客户端请求到达 Cloudflare 边缘,触发 Worker 的fetch处理器;
  2. wrangler 注入的 secrets 通过env绑定对象进入函数作用域;
  3. createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY)完成 Supabase 客户端初始化;
  4. supabase.from('articles').select('*')向 Supabase 项目发起查询,读取 Postgres 中articles表的记录;
  5. JSON.stringify(data)序列化查询结果,配合Content-Type: application/json响应头封装为Response返回给调用方。

从源码结构可以进一步推断该架构的扩展方向:若需要“先返回响应、再后台刷新缓存”的体验,可参考仓库中的 with-cloudflare-workers-kv 示例,借助 Workers 的context.waitUntil在响应返回后继续更新 KV 缓存——这与本示例共用同一套 Supabase 客户端初始化与密钥注入模式,可作为继续深入学习的下一站。

需要注意的边界

  • 密钥定位SUPABASE_PUBLISHABLE_KEY(Anon Key)设计上允许暴露在客户端与边缘代码中,但它仍受网关与数据库 RLS 策略约束;切勿把高权限的service_role密钥放入 Worker 前端代码。
  • 运行时差异:示例锁定的 wrangler 版本为2.20.1、compatibility_date 为2022-07-26。使用更新版本 wrangler 时,个别命令(如publishdev)的行为可能存在差异,但 secret 注入、env绑定与fetch模块约定是稳定的核心模型。
  • 示例用途:该目录是一个教学性质的最小示例,未包含鉴权、错误处理与分页逻辑;投入生产前应补充data为空的兜底、查询失败的状态码返回以及基于 RLS 的数据可见性控制。

通过本示例可以看到,借助@supabase/supabase-js与 wrangler 的 secrets 机制,把 Supabase 数据查询下沉到 Cloudflare Worker 仅需一个入口文件即可完成。读者可直接在仓库中对照 README.md、src/index.js 与 wrangler.toml 三个文件进行实践。

【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询