4.8.3 拓展:离用户最近的计算——Edge Functions:边缘计算函数
一句话破题
Edge Functions 让代码在全球边缘节点运行——离用户最近,响应最快,还能安全访问敏感 API。
Edge Functions 是什么?
特点:
- 基于 Deno 运行时
- 全球分布式部署
- 冷启动快(毫秒级)
- 支持 TypeScript
创建 Edge Function
bash
# 安装 Supabase CLI
npm install -g supabase
# 初始化项目(如果还没有)
supabase init
# 创建函数
supabase functions new hello-world目录结构:
supabase/
└── functions/
└── hello-world/
└── index.ts基础函数示例
typescript
// supabase/functions/hello-world/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
serve(async (req: Request) => {
const { name } = await req.json()
return new Response(
JSON.stringify({ message: `Hello ${name}!` }),
{ headers: { "Content-Type": "application/json" } }
)
})本地开发
bash
# 启动本地函数服务
supabase functions serve
# 测试函数
curl -i --location --request POST \
'http://localhost:54321/functions/v1/hello-world' \
--header 'Content-Type: application/json' \
--data '{"name":"World"}'部署函数
bash
# 部署单个函数
supabase functions deploy hello-world
# 部署所有函数
supabase functions deploy访问 Supabase 服务
typescript
// supabase/functions/get-user/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
import { createClient } from "https://esm.sh/@supabase/supabase-js@2"
serve(async (req: Request) => {
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
)
const authHeader = req.headers.get('Authorization')!
const token = authHeader.replace('Bearer ', '')
const { data: { user } } = await supabase.auth.getUser(token)
if (!user) {
return new Response(
JSON.stringify({ error: 'Unauthorized' }),
{ status: 401 }
)
}
const { data, error } = await supabase
.from('profiles')
.select('*')
.eq('id', user.id)
.single()
return new Response(
JSON.stringify(data),
{ headers: { "Content-Type": "application/json" } }
)
})调用第三方 API
typescript
// supabase/functions/send-email/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
serve(async (req: Request) => {
const { to, subject, body } = await req.json()
const response = await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${Deno.env.get('RESEND_API_KEY')}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: 'noreply@example.com',
to,
subject,
html: body
})
})
const result = await response.json()
return new Response(
JSON.stringify(result),
{ headers: { "Content-Type": "application/json" } }
)
})设置环境变量
bash
# 设置密钥
supabase secrets set RESEND_API_KEY=re_xxxx
# 查看所有密钥
supabase secrets list在前端调用
typescript
import { supabase } from '@/lib/supabase'
async function sendWelcomeEmail(userEmail: string) {
const { data, error } = await supabase.functions.invoke('send-email', {
body: {
to: userEmail,
subject: '欢迎加入',
body: '<h1>欢迎!</h1>'
}
})
if (error) throw error
return data
}Webhook 处理
typescript
// supabase/functions/stripe-webhook/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
import Stripe from "https://esm.sh/stripe@12.0.0?target=deno"
const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!, {
apiVersion: '2023-10-16'
})
serve(async (req: Request) => {
const signature = req.headers.get('stripe-signature')!
const body = await req.text()
let event: Stripe.Event
try {
event = stripe.webhooks.constructEvent(
body,
signature,
Deno.env.get('STRIPE_WEBHOOK_SECRET')!
)
} catch (err) {
return new Response(
JSON.stringify({ error: 'Invalid signature' }),
{ status: 400 }
)
}
switch (event.type) {
case 'checkout.session.completed':
// 处理支付成功
break
case 'customer.subscription.deleted':
// 处理订阅取消
break
}
return new Response(JSON.stringify({ received: true }))
})常见用例
| 用例 | 说明 |
|---|---|
| 发送邮件 | 调用 Resend/SendGrid 等服务 |
| 处理支付 | Stripe/PayPal Webhook |
| 图片处理 | 生成缩略图、水印 |
| AI 调用 | 调用 OpenAI 等 API |
| 定时任务 | 配合 Cron 触发 |
本节小结
- Edge Functions 基于 Deno,使用 TypeScript
- 适合调用第三方 API、处理 Webhook
- 使用
supabase secrets管理敏感配置 - 通过
supabase.functions.invoke在前端调用
