Supabase
从 Deno 直连 Supabase Postgres 或使用 supabase-js,覆盖连接池端口、RLS、Edge Functions 与密钥边界
Supabase 的两条接入路径:把它当托管 Postgres 直连(配合 Drizzle/postgres.js,见 PostgreSQL 与 Drizzle),或用官方 SDK @supabase/supabase-js 走 PostgREST/Auth/Storage API。SDK 同时发布在 npm 和 JSR(jsr:@supabase/supabase-js)上。
import { createClient } from "jsr:@supabase/supabase-js@2";
const url = Deno.env.get("SUPABASE_URL");
const key = Deno.env.get("SUPABASE_PUBLISHABLE_KEY");
if (!url || !key) throw new Error("SUPABASE_URL / SUPABASE_PUBLISHABLE_KEY required");
export const supabase = createClient(url, key);
deno run \
--allow-env=SUPABASE_URL,SUPABASE_PUBLISHABLE_KEY \
--allow-net=<project-ref>.supabase.co \
src/main.ts
直连 Postgres 与连接池
Supabase 提供多种连接方式,端口与适用场景(官方连接文档):
| 方式 | 主机:端口 | 适用 |
|---|---|---|
| Direct connection | db.<project-ref>.supabase.co:5432 | 常驻服务、migration、pg_dump;IPv6,IPv4 需付费 add-on |
| Supavisor session 模式 | aws-<region>.pooler.supabase.com:5432 | IPv4-only 网络的直连替代 |
| Supavisor transaction 模式 | aws-<region>.pooler.supabase.com:6543 | serverless / 边缘函数等大量短连接 |
- Deno Deploy 一类无常驻进程的环境用 transaction 模式(6543);官方明确 transaction 模式不支持 prepared statements,客户端要禁用(
postgres.js:postgres(url, { prepare: false }))。 - serverless 并发扩容时按最大实例数核算总连接数,池上限别按单实例拍。
- migration 用 direct connection 或 session 模式,走独立发布步骤,不给线上 HTTP 进程 schema 修改权限。
deno run \
--allow-env=DATABASE_URL \
--allow-net=aws-<region>.pooler.supabase.com:6543 \
src/main.ts
Auth 与 RLS 边界
- SDK 默认按调用者身份执行:新 publishable key(对应 legacy anon JWT key,两者是可并存的不同密钥类型而非简单改名)+ 用户 JWT 时,PostgREST 以该用户角色访问,RLS 策略生效。
- 官方 RLS 文档要求暴露 schema(默认
public)中的表必须启用 RLS;启用后没有策略则 publishable key 下 API 不可读任何数据。Table Editor 建表默认开启,手写 SQL 建表要自己enable row level security。 - 新 secret key(对应 legacy service_role JWT key)会绕过 RLS,官方明确禁止出现在浏览器或交付给客户的代码里;只在服务端、从环境变量注入、不进日志。
- Deno 后端如果只做受信服务间调用,直连 Postgres 往往比 service key + PostgREST 更直观;需要按终端用户鉴权时才走 SDK + RLS。
Edge Functions 与本地 Deno 的差异
Supabase Edge Functions 运行在 Supabase Edge Runtime 上——官方称其为 Deno 兼容、TypeScript 优先的运行时(开源,github.com/supabase/edge-runtime)。与本地 Deno 的实际差异:
- 依赖导入支持
npm:、jsr:和 Node 内置模块;官方推荐每个函数配自己的deno.json,部署时不要共享/supabase/functions下的全局配置。 - 本地用
supabase functions serve获得与生产接近的运行时,部署用supabase functions deploy。 - 函数面向短生命周期、幂等操作设计,可能有冷启动;长任务交给后台 worker,不要塞进函数。
- 它是 Deno 兼容运行时而非 Deno 本体,不要假设与本地
deno版本特性完全对齐;用到新 API 前在 Edge Runtime 仓库核对。
密钥管理
- 只需要 publishable 级别的权限就不要引入 secret key;两者用不同环境变量名分开,避免误用。
- secret 只从环境或 secret store 读取,不进源码、日志和错误响应;轮换时按 Supabase dashboard 的密钥滚动流程走。
--allow-env精确到变量名,--allow-net精确到项目主机;CI 加--no-prompt。
官方参考:Connecting to your database、Row Level Security、Edge Functions、Function dependencies、Deno 官方 Supabase 示例。