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

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

2026-09-06 19:25:45作者:余洋婵Anita

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_KEYnextjs-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 大版本;开发依赖 wrangler CLI(此示例锁定在 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.mdsrc/index.jswrangler.toml 三个文件进行实践。

登录后查看全文
热门项目推荐
相关项目推荐