⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议
Skip to content

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 在前端调用