supabase-edge-functions
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSupabase Edge Functions
Supabase Edge Functions
Overview
概述
This skill provides operations for working with Supabase Edge Functions - serverless TypeScript/JavaScript functions that run on Deno Deploy. Use for invoking functions, deploying code, and managing function lifecycles.
本技能提供了操作Supabase Edge Functions的相关功能——这是运行在Deno Deploy上的无服务器TypeScript/JavaScript函数。可用于调用函数、部署代码以及管理函数生命周期。
Prerequisites
前提条件
Required environment variables:
bash
export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_KEY="your-anon-or-service-role-key"Required tools:
- Supabase CLI (command)
supabase - Deno (for local development)
Install Supabase CLI:
bash
undefined必需的环境变量:
bash
export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_KEY="your-anon-or-service-role-key"必需的工具:
- Supabase CLI(命令)
supabase - Deno(用于本地开发)
安装Supabase CLI:
bash
undefinedmacOS
macOS
brew install supabase/tap/supabase
brew install supabase/tap/supabase
Linux
Linux
curl -fsSL https://github.com/supabase/cli/releases/latest/download/supabase_linux_amd64.tar.gz | tar -xz
sudo mv supabase /usr/local/bin/
curl -fsSL https://github.com/supabase/cli/releases/latest/download/supabase_linux_amd64.tar.gz | tar -xz
sudo mv supabase /usr/local/bin/
Windows (PowerShell)
Windows (PowerShell)
scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase
**Helper script:**
This skill uses the shared Supabase API helper for invoking functions:
```bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase
**辅助脚本:**
本技能使用共享的Supabase API辅助脚本来调用函数:
```bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"Invoke Edge Functions
调用Edge Functions
Basic Invocation
基础调用
Invoke a function with POST:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="hello-world"
supabase_post "/functions/v1/${FUNCTION_NAME}" '{
"name": "Alice"
}'Invoke with GET:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="get-data"
supabase_get "/functions/v1/${FUNCTION_NAME}?id=123"使用POST调用函数:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="hello-world"
supabase_post "/functions/v1/${FUNCTION_NAME}" '{
"name": "Alice"
}'使用GET调用:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="get-data"
supabase_get "/functions/v1/${FUNCTION_NAME}?id=123"Invoke with Headers
携带Header调用
Pass custom headers:
bash
FUNCTION_NAME="authenticated-function"
USER_TOKEN="user-access-token"
curl -s -X POST \
"${SUPABASE_URL}/functions/v1/${FUNCTION_NAME}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${USER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"action": "process"}'传递自定义Header:
bash
FUNCTION_NAME="authenticated-function"
USER_TOKEN="user-access-token"
curl -s -X POST \
"${SUPABASE_URL}/functions/v1/${FUNCTION_NAME}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${USER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"action": "process"}'Invoke with Authentication
携带认证信息调用
Invoke function as authenticated user:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="user-profile"
ACCESS_TOKEN="user-jwt-token"
curl -s -X POST \
"${SUPABASE_URL}/functions/v1/${FUNCTION_NAME}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{}'以认证用户身份调用函数:
bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="user-profile"
ACCESS_TOKEN="user-jwt-token"
curl -s -X POST \
"${SUPABASE_URL}/functions/v1/${FUNCTION_NAME}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{}'Function Management (CLI)
函数管理(CLI)
Initialize Function
初始化函数
Create a new edge function:
bash
undefined创建新的Edge函数:
bash
undefinedNavigate to your Supabase project directory
导航到你的Supabase项目目录
cd /path/to/project
cd /path/to/project
Create new function
创建新函数
supabase functions new my-function
supabase functions new my-function
This creates: supabase/functions/my-function/index.ts
这会生成:supabase/functions/my-function/index.ts
undefinedundefinedFunction Template
函数模板
Basic function structure:
typescript
// supabase/functions/my-function/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
serve(async (req) => {
const { name } = await req.json()
const data = {
message: `Hello ${name}!`,
}
return new Response(
JSON.stringify(data),
{ headers: { "Content-Type": "application/json" } },
)
})Function with authentication:
typescript
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) => {
// Get JWT from Authorization header
const authHeader = req.headers.get('Authorization')!
const token = authHeader.replace('Bearer ', '')
// Create Supabase client with user's token
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_ANON_KEY') ?? '',
{ global: { headers: { Authorization: authHeader } } }
)
// Get authenticated user
const { data: { user }, error } = await supabase.auth.getUser(token)
if (error || !user) {
return new Response('Unauthorized', { status: 401 })
}
return new Response(
JSON.stringify({ message: `Hello ${user.email}!` }),
{ headers: { "Content-Type": "application/json" } },
)
})基础函数结构:
typescript
// supabase/functions/my-function/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
serve(async (req) => {
const { name } = await req.json()
const data = {
message: `Hello ${name}!`,
}
return new Response(
JSON.stringify(data),
{ headers: { "Content-Type": "application/json" } },
)
})带认证的函数:
typescript
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) => {
// 从Authorization Header获取JWT
const authHeader = req.headers.get('Authorization')!
const token = authHeader.replace('Bearer ', '')
// 使用用户的token创建Supabase客户端
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_ANON_KEY') ?? '',
{ global: { headers: { Authorization: authHeader } } }
)
// 获取认证用户
const { data: { user }, error } = await supabase.auth.getUser(token)
if (error || !user) {
return new Response('Unauthorized', { status: 401 })
}
return new Response(
JSON.stringify({ message: `Hello ${user.email}!` }),
{ headers: { "Content-Type": "application/json" } },
)
})Deploy Function
部署函数
Deploy a function to Supabase:
bash
undefined将函数部署到Supabase:
bash
undefinedLogin to Supabase (first time only)
登录Supabase(仅首次需要)
supabase login
supabase login
Link to your project (first time only)
关联到你的项目(仅首次需要)
supabase link --project-ref your-project-ref
supabase link --project-ref your-project-ref
Deploy specific function
部署指定函数
supabase functions deploy my-function
supabase functions deploy my-function
Deploy with custom environment variables
携带自定义环境变量部署
supabase functions deploy my-function
--env-file ./supabase/.env.local
--env-file ./supabase/.env.local
supabase functions deploy my-function
--env-file ./supabase/.env.local
--env-file ./supabase/.env.local
Deploy all functions
部署所有函数
supabase functions deploy
undefinedsupabase functions deploy
undefinedSet Environment Variables
设置环境变量
Set secrets for edge functions:
bash
undefined为Edge函数设置密钥:
bash
undefinedSet individual secret
设置单个密钥
supabase secrets set MY_SECRET_KEY=value123
supabase secrets set MY_SECRET_KEY=value123
Set multiple secrets from file
从文件设置多个密钥
Create .env file:
创建.env文件:
API_KEY=abc123
API_KEY=abc123
DATABASE_URL=postgres://...
DATABASE_URL=postgres://...
supabase secrets set --env-file .env
supabase secrets set --env-file .env
List secrets (names only, not values)
列出密钥(仅显示名称,不显示值)
supabase secrets list
supabase secrets list
Unset secret
删除密钥
supabase secrets unset MY_SECRET_KEY
undefinedsupabase secrets unset MY_SECRET_KEY
undefinedLocal Development
本地开发
Run functions locally:
bash
undefined本地运行函数:
bash
undefinedStart local Supabase (includes edge functions)
启动本地Supabase(包含Edge函数)
supabase start
supabase start
Serve functions locally
本地运行函数
supabase functions serve
supabase functions serve
Serve specific function
本地运行指定函数
supabase functions serve my-function --env-file ./supabase/.env.local
supabase functions serve my-function --env-file ./supabase/.env.local
Invoke local function
调用本地函数
curl http://localhost:54321/functions/v1/my-function
-H "Authorization: Bearer ${SUPABASE_KEY}"
-d '{"name": "test"}'
-H "Authorization: Bearer ${SUPABASE_KEY}"
-d '{"name": "test"}'
undefinedcurl http://localhost:54321/functions/v1/my-function
-H "Authorization: Bearer ${SUPABASE_KEY}"
-d '{"name": "test"}'
-H "Authorization: Bearer ${SUPABASE_KEY}"
-d '{"name": "test"}'
undefinedDelete Function
删除函数
Remove a deployed function:
bash
undefined删除已部署的函数:
bash
undefinedDelete function from Supabase dashboard or using SQL
从Supabase控制台或使用SQL删除函数
Note: No direct CLI command to delete, must use dashboard
注意:没有直接的CLI命令可以删除,必须使用控制台
Remove local function file
删除本地函数文件
rm -rf supabase/functions/my-function
undefinedrm -rf supabase/functions/my-function
undefinedCommon Patterns
常见模式
Invoke and Process Response
调用并处理响应
bash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="process-data"
response=$(supabase_post "/functions/v1/${FUNCTION_NAME}" '{
"action": "calculate",
"values": [1, 2, 3, 4, 5]
}')
if [[ $? -eq 0 ]]; then
result=$(echo "$response" | jq -r '.result')
echo "Function result: $result"
else
echo "Function invocation failed"
exit 1
fibash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="process-data"
response=$(supabase_post "/functions/v1/${FUNCTION_NAME}" '{
"action": "calculate",
"values": [1, 2, 3, 4, 5]
}')
if [[ $? -eq 0 ]]; then
result=$(echo "$response" | jq -r '.result')
echo "函数结果:$result"
else
echo "函数调用失败"
exit 1
fiBatch Function Invocations
批量调用函数
bash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="send-email"
RECIPIENTS=("alice@example.com" "bob@example.com" "charlie@example.com")
for email in "${RECIPIENTS[@]}"; do
echo "Processing $email..."
supabase_post "/functions/v1/${FUNCTION_NAME}" '{
"to": "'"$email"'",
"subject": "Hello",
"body": "Test message"
}'
echo "✓ Sent to $email"
donebash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
FUNCTION_NAME="send-email"
RECIPIENTS=("alice@example.com" "bob@example.com" "charlie@example.com")
for email in "${RECIPIENTS[@]}"; do
echo "正在处理$email..."
supabase_post "/functions/v1/${FUNCTION_NAME}" '{
"to": "'"$email"'",
"subject": "Hello",
"body": "Test message"
}'
echo "✓ 已发送给$email"
doneFunction with Retry Logic
带重试逻辑的函数调用
bash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
invoke_with_retry() {
local function_name="$1"
local payload="$2"
local max_retries=3
local retry_count=0
while [[ $retry_count -lt $max_retries ]]; do
if response=$(supabase_post "/functions/v1/${function_name}" "$payload" 2>&1); then
echo "$response"
return 0
else
retry_count=$((retry_count + 1))
echo "Retry $retry_count/$max_retries..." >&2
sleep 2
fi
done
echo "Function failed after $max_retries retries" >&2
return 1
}bash
#!/bin/bash
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/supabase-api.sh"
invoke_with_retry() {
local function_name="$1"
local payload="$2"
local max_retries=3
local retry_count=0
while [[ $retry_count -lt $max_retries ]]; do
if response=$(supabase_post "/functions/v1/${function_name}" "$payload" 2>&1); then
echo "$response"
return 0
else
retry_count=$((retry_count + 1))
echo "正在重试 $retry_count/$max_retries..." >&2
sleep 2
fi
done
echo "函数在$max_retries次重试后仍失败" >&2
return 1
}Use it
使用示例
invoke_with_retry "my-function" '{"action": "process"}'
undefinedinvoke_with_retry "my-function" '{"action": "process"}'
undefinedDeploy Function Script
函数部署脚本
bash
#!/bin/bashbash
#!/bin/bashdeploy-function.sh
deploy-function.sh
FUNCTION_NAME="${1:-my-function}"
echo "Deploying function: $FUNCTION_NAME"
FUNCTION_NAME="${1:-my-function}"
echo "正在部署函数:$FUNCTION_NAME"
Validate function exists
验证函数是否存在
if [[ ! -d "supabase/functions/$FUNCTION_NAME" ]]; then
echo "Error: Function $FUNCTION_NAME not found"
exit 1
fi
if [[ ! -d "supabase/functions/$FUNCTION_NAME" ]]; then
echo "错误:未找到函数$FUNCTION_NAME"
exit 1
fi
Deploy
部署函数
if supabase functions deploy "$FUNCTION_NAME"; then
echo "✓ Deployed successfully"
# Test invocation
echo "Testing function..."
response=$(curl -s -X POST \
"${SUPABASE_URL}/functions/v1/${FUNCTION_NAME}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Content-Type: application/json" \
-d '{}')
echo "Test response: $response"else
echo "✗ Deployment failed"
exit 1
fi
undefinedif supabase functions deploy "$FUNCTION_NAME"; then
echo "✓ 部署成功"
# 测试调用
echo "正在测试函数..."
response=$(curl -s -X POST \
"${SUPABASE_URL}/functions/v1/${FUNCTION_NAME}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Content-Type: application/json" \
-d '{}')
echo "测试响应:$response"else
echo "✗ 部署失败"
exit 1
fi
undefinedMonitor Function Logs
监控函数日志
bash
undefinedbash
undefinedView function logs (requires Supabase CLI)
查看函数日志(需要Supabase CLI)
supabase functions logs my-function
supabase functions logs my-function
Follow logs in real-time
实时跟踪日志
supabase functions logs my-function --follow
supabase functions logs my-function --follow
Filter logs by level
按级别过滤日志
supabase functions logs my-function --level error
supabase functions logs my-function --level error
View logs from specific time
查看指定时间范围内的日志
supabase functions logs my-function --since 1h
undefinedsupabase functions logs my-function --since 1h
undefinedAdvanced Patterns
高级模式
Function with Database Access
访问数据库的函数
typescript
// supabase/functions/get-user-data/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) => {
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
)
const { userId } = await req.json()
const { data, error } = await supabase
.from('users')
.select('*')
.eq('id', userId)
.single()
if (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
})
}
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' }
})
})typescript
// supabase/functions/get-user-data/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) => {
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
)
const { userId } = await req.json()
const { data, error } = await supabase
.from('users')
.select('*')
.eq('id', userId)
.single()
if (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
})
}
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' }
})
})Function with External API Call
调用外部API的函数
typescript
// supabase/functions/fetch-weather/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
serve(async (req) => {
const { city } = await req.json()
const apiKey = Deno.env.get('WEATHER_API_KEY')
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`
)
const data = await response.json()
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' }
})
})typescript
// supabase/functions/fetch-weather/index.ts
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
serve(async (req) => {
const { city } = await req.json()
const apiKey = Deno.env.get('WEATHER_API_KEY')
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`
)
const data = await response.json()
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' }
})
})Scheduled Function (Cron)
定时函数(Cron)
typescript
// supabase/functions/daily-cleanup/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) => {
// Verify request is from Supabase Cron
const authHeader = req.headers.get('Authorization')
if (authHeader !== `Bearer ${Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')}`) {
return new Response('Unauthorized', { status: 401 })
}
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
)
// Delete old records
const { data, error } = await supabase
.from('logs')
.delete()
.lt('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString())
return new Response(JSON.stringify({ deleted: data?.length ?? 0 }), {
headers: { 'Content-Type': 'application/json' }
})
})Set up cron job in Supabase Dashboard:
sql
-- In SQL Editor, create pg_cron job:
select cron.schedule(
'daily-cleanup',
'0 2 * * *', -- Run at 2 AM daily
$$
select
net.http_post(
url := 'https://your-project.supabase.co/functions/v1/daily-cleanup',
headers := '{"Content-Type": "application/json", "Authorization": "Bearer YOUR_SERVICE_ROLE_KEY"}'::jsonb,
body := '{}'::jsonb
) as request_id;
$$
);typescript
// supabase/functions/daily-cleanup/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) => {
// 验证请求来自Supabase Cron
const authHeader = req.headers.get('Authorization')
if (authHeader !== `Bearer ${Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')}`) {
return new Response('Unauthorized', { status: 401 })
}
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
)
// 删除旧记录
const { data, error } = await supabase
.from('logs')
.delete()
.lt('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString())
return new Response(JSON.stringify({ deleted: data?.length ?? 0 }), {
headers: { 'Content-Type': 'application/json' }
})
})在Supabase控制台设置定时任务:
sql
-- 在SQL编辑器中,创建pg_cron任务:
select cron.schedule(
'daily-cleanup',
'0 2 * * *', -- 每天凌晨2点运行
$$
select
net.http_post(
url := 'https://your-project.supabase.co/functions/v1/daily-cleanup',
headers := '{"Content-Type": "application/json", "Authorization": "Bearer YOUR_SERVICE_ROLE_KEY"}'::jsonb,
body := '{}'::jsonb
) as request_id;
$$
);Testing Functions
测试函数
Test Locally
本地测试
bash
undefinedbash
undefinedStart local environment
启动本地环境
supabase start
supabase start
Serve function
运行函数
supabase functions serve my-function
supabase functions serve my-function
Test with curl
使用curl测试
curl http://localhost:54321/functions/v1/my-function
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
-d '{"test": "data"}'
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
-d '{"test": "data"}'
undefinedcurl http://localhost:54321/functions/v1/my-function
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
-d '{"test": "data"}'
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
-d '{"test": "data"}'
undefinedIntegration Test Script
集成测试脚本
bash
#!/bin/bashbash
#!/bin/bashtest-function.sh
test-function.sh
FUNCTION_NAME="$1"
TEST_CASES_FILE="$2"
if [[ ! -f "$TEST_CASES_FILE" ]]; then
echo "Test cases file not found"
exit 1
fi
echo "Testing function: $FUNCTION_NAME"
while IFS= read -r test_case; do
echo "Test case: $test_case"
response=$(curl -s -X POST \
"${SUPABASE_URL}/functions/v1/${FUNCTION_NAME}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Content-Type: application/json" \
-d "$test_case")
echo "Response: $response"
echo "---"done < "$TEST_CASES_FILE"
undefinedFUNCTION_NAME="$1"
TEST_CASES_FILE="$2"
if [[ ! -f "$TEST_CASES_FILE" ]]; then
echo "未找到测试用例文件"
exit 1
fi
echo "正在测试函数:$FUNCTION_NAME"
while IFS= read -r test_case; do
echo "测试用例:$test_case"
response=$(curl -s -X POST \
"${SUPABASE_URL}/functions/v1/${FUNCTION_NAME}" \
-H "apikey: ${SUPABASE_KEY}" \
-H "Content-Type: application/json" \
-d "$test_case")
echo "响应:$response"
echo "---"done < "$TEST_CASES_FILE"
undefinedError Handling
错误处理
Function errors return HTTP status codes:
| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request (invalid input) |
| 401 | Unauthorized (invalid/missing auth) |
| 403 | Forbidden (insufficient permissions) |
| 500 | Internal server error (function crashed) |
| 504 | Gateway timeout (function took too long) |
Timeout limit: Edge functions have a 2-second CPU time limit and 150-second wall clock timeout.
函数错误会返回对应的HTTP状态码:
| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 400 | 请求错误(输入无效) |
| 401 | 未认证(认证信息无效/缺失) |
| 403 | 禁止访问(权限不足) |
| 500 | 服务器内部错误(函数崩溃) |
| 504 | 网关超时(函数执行时间过长) |
超时限制: Edge函数的CPU时间限制为2秒,挂钟时间超时限制为150秒。
Security Best Practices
安全最佳实践
- Validate input: Always validate and sanitize request data
- Use service role key carefully: Only in admin functions, never expose to clients
- Implement authentication: Check user tokens for protected functions
- Rate limiting: Implement rate limiting for public functions
- Environment variables: Store secrets in Supabase secrets, not in code
- CORS: Configure CORS headers appropriately
- Error messages: Don't leak sensitive information in error responses
- 验证输入:始终验证并清理请求数据
- 谨慎使用服务角色密钥:仅在管理员函数中使用,绝不能暴露给客户端
- 实现认证机制:对受保护的函数检查用户token
- 速率限制:对公共函数实现速率限制
- 环境变量:将密钥存储在Supabase密钥中,不要放在代码里
- CORS:合理配置CORS Header
- 错误信息:不要在错误响应中泄露敏感信息
Performance Tips
性能优化技巧
- Cold starts: Functions may have cold starts (100-200ms delay)
- Keep functions small: Faster cold starts and easier debugging
- Cache external data: Use in-memory caching for repeated API calls
- Parallel execution: Use for concurrent operations
Promise.all() - Stream large responses: Use streaming for large data transfers
- 冷启动:函数可能会有冷启动(100-200毫秒延迟)
- 保持函数精简:冷启动更快,调试更简单
- 缓存外部数据:对重复的API调用使用内存缓存
- 并行执行:使用进行并发操作
Promise.all() - 流式传输大响应:对大数据传输使用流式处理
API Documentation
API文档
- Supabase Edge Functions: https://supabase.com/docs/guides/functions
- Deno Deploy: https://deno.com/deploy/docs
- Supabase Edge Functions:https://supabase.com/docs/guides/functions
- Deno Deploy:https://deno.com/deploy/docs