用途
该技能用于在 Supabase 项目中实现数据库 Webhooks、pg_net 异步 HTTP、LISTEN/NOTIFY 以及带签名校验的 Edge Function 事件处理器。它面向需要把数据库行变更与外部服务或客户端 UI 联动的开发场景,提供可参考的生产级代码模式。
主要能力
Supabase 提供四种互补的事件机制:
- 数据库 Webhooks:通过基于 pg_net 的触发器发起 HTTP 调用。
- supabase_functions.http_request():从触发器调用 Edge Functions。
- Postgres LISTEN/NOTIFY:轻量级发布/订阅。
- Realtime postgres_changes:客户端事件订阅。
技能覆盖这四类模式,内容涉及签名校验、幂等性与重试处理。
鉴权
Webhook 双向均需鉴权:
- 出站(触发器 → Edge Function):触发器发送 Authorization: Bearer <service_role_key> 请求头。密钥应存储在 Postgres 设置(app.settings.service_role_key)或 Supabase Vault 中,不要内联写入已提交的迁移文件。
- 入站(Edge Function 接收器):使用常量时间比较,对共享的 WEBHOOK_SECRET(从 Deno.env 读取)校验 HMAC-SHA256 签名,不匹配时返回 401。相关细节见 signature-verification.md。
使用方式
按消费者选择机制:服务端 HTTP 扇出用 pg_net 触发器,需签名处理的用 Edge Function 接收器,库内发布订阅用 LISTEN/NOTIFY,客户端 UI 用 Realtime。每个 SQL 触发器写入 supabase/migrations/ 文件,每个处理器写入 supabase/functions/<name>/index.ts,再用 supabase CLI 应用和部署。
步骤 1:使用 pg_net 与触发器函数的数据库 Webhooks
启用 pg_net,然后编写触发器函数,把变更行 POST 到 Edge Function,并挂载到 AFTER INSERT/UPDATE/DELETE。完整的触发器集合(条件状态变更触发器、内置辅助函数 supabase_functions.http_request()、net._http_response 检查查询)见 database-webhooks.md。
CREATE EXTENSION IF NOT EXISTS pg_net WITH SCHEMA extensions;
CREATE OR REPLACE FUNCTION public.notify_order_created()
RETURNS trigger AS $$
BEGIN
PERFORM net.http_post(
url := 'https://<project-ref>.supabase.co/functions/v1/on-order-created',
headers := jsonb_build_object('Content-Type', 'application/json'),
body := jsonb_build_object('type', TG_OP, 'record', row_to_json(NEW)::jsonb)
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER on_order_created
AFTER INSERT ON public.orders
FOR EACH ROW EXECUTE FUNCTION public.notify_order_created();
步骤 2:带签名校验的 Edge Function Webhook 接收器
编写 Edge Function:读取原始请求体、校验 HMAC 签名、解析带类型的载荷并按事件类型路由。用 processed_events 幂等表防止重复投递。完整接收器、幂等处理器变体和幂等表 DDL 见 edge-function-receivers.md。
// supabase/functions/on-order-created/index.ts
serve(async (req) => {
const rawBody = await req.text();
const secret = Deno.env.get("WEBHOOK_SECRET");
if (secret) {
const sig = req.headers.get("x-webhook-signature") ?? "";
if (!(await verifySignature(rawBody, sig, secret)))
return new Response(JSON.stringify({ error: "Invalid signature" }), { status: 401 });
}
const payload = JSON.parse(rawBody); // { type, table, record, old_record }
// route by payload.type: INSERT | UPDATE | DELETE
return new Response(JSON.stringify({ received: true }));
});
步骤 3:Postgres LISTEN/NOTIFY 与 Realtime 作为事件源
在触发器中用 pg_notify 实现轻量、非持久化的发布订阅,由后端 LISTEN 消费;客户端 UI 订阅使用 Realtime postgres_changes(NOTIFY 载荷只放 ID——超过 8000 字节会被截断)。后端监听器、完整的 Realtime 订阅与事件路由,以及结合服务端与客户端的事件驱动架构图见 listen-notify-realtime.md。
const channel = supabase
.channel("orders-events")
.on("postgres_changes",
{ event: "*", schema: "public", table: "orders" },
(payload) => console.log(payload.eventType, payload.new))
.subscribe();
输出
这些模式可产出:
- 在行变更时通过 pg_net 调用 Edge Functions 的数据库触发器函数
- 仅在特定列变更时触发的条件触发器
- 带 HMAC 签名校验的 Edge Function Webhook 接收器
- 防止重复副作用的幂等事件处理
- 用于轻量服务间通信的 LISTEN/NOTIFY 通道
- 用于实时客户端 UI 更新的 Realtime 订阅
- 结合服务端与客户端模式的事件驱动架构
错误处理
| 错误 | 原因 | 修复 |
|---|---|---|
| pg_net 返回 404 | Edge Function 未部署或 URL 错误 | 运行 supabase functions deploy <name> 并确认 URL 匹配 |
| Webhook 未触发 | 触发器未挂载或表不在 publication 中 | 检查 SELECT * FROM pg_trigger WHERE tgrelid = 'orders'::regclass; |
| 处理了重复事件 | 缺少幂等层 | 添加带唯一 event_id 约束的 processed_events 表 |
| Realtime 收不到 | 表未加入 Realtime publication | 在控制台 Database > Replication 中启用该表 |
| net._http_response 显示 401 | 鉴权头无效或缺失 | 确认 service_role_key 已设置在 app.settings 或 vault 中 |
| NOTIFY 载荷被截断 | 载荷超过 8000 字节 | NOTIFY 中只发送 ID,在监听器中获取完整记录 |
| Auth hook 报错 | 函数抛出异常 | 查看 Dashboard > Logs > Auth;确保函数返回有效 JSONB |
| 触发器静默失败 | SECURITY DEFINER 未设置 search_path | 为函数添加 SET search_path = public, extensions; |
配套文档
- database-webhooks.md — 完整 pg_net 触发器集合:条件状态变更触发器、supabase_functions.http_request() 辅助函数、net._http_response 检查查询。
- edge-function-receivers.md — 完整的已签名 Edge Function 接收器、幂等处理器和幂等表 DDL。
- listen-notify-realtime.md — 后端 LISTEN 客户端、完整 Realtime 订阅和结合的事件驱动架构图。
- examples.md — 使用 ngrok 和 curl 进行本地 Webhook 测试。
- signature-verification.md — Node.js HMAC 签名校验。
- event-handler-pattern.md — 带类型的事件分发器模式。
前置条件
- 已安装 supabase CLI 的 Supabase 项目(本地或托管)
- 已启用 pg_net 扩展:控制台 > Database > Extensions > 搜索 "pg_net" > 启用
- 客户端模式需安装 @supabase/supabase-js v2+
- Webhook 接收器模式需已部署 Edge Functions
适用场景
需要在数据库变更时触发外部 HTTP 调用、在 Edge Function 中安全处理带签名的事件、在同一数据库内做轻量服务间通信,或让客户端 UI 实时响应数据变化的 Supabase 项目。
限制
资料仅提供上述机制与示例,未给出独立的价格、平台或性能数据;NOTIFY 载荷超过 8000 字节会被截断;相关扩展与部署需自行完成。性能优化见 supabase-performance-tuning,生产加固(包括 Webhook 访问表的 RLS 策略)见 supabase-security-basics。