Supabase는 데이터베이스와 인증을 넘어 Edge Functions라는 서버리스 실행 환경을 제공한다. Node.js가 아닌 Deno 런타임 위에서 동작하기 때문에 TypeScript를 별도 컴파일 없이 바로 실행할 수 있다. Webhook 처리, 외부 API 호출, AI 연동까지 단일 플랫폼 안에서 해결할 수 있어 별도 백엔드 서버 없이도 복잡한 로직을 배포할 수 있다.
Edge Functions는 Cloudflare Workers와 유사한 V8 Isolate 모델로 동작한다. 각 함수 호출은 독립된 격리 환경에서 실행되며, 콜드 스타트가 수십 밀리초 수준으로 매우 짧다.
클라이언트 요청
│
▼
┌─────────────────┐
│ Supabase CDN │ 글로벌 엣지 노드
└────────┬────────┘
│
▼
┌─────────────────┐
│ Deno Isolate │ 함수 코드 실행
│ (Edge Fn) │
└────────┬────────┘
│
┌────┴─────┐
▼ ▼
Supabase 외부 API
DB / Auth
V8 Isolate — Node.js 프로세스 대신 V8 엔진의 격리된 컨텍스트를 사용해 메모리를 공유하지 않는 경량 실행 단위.
Supabase CLI로 함수를 생성하고 배포한다.
# 함수 생성
supabase functions new hello-world
# 로컬 실행 (핫 리로드)
supabase functions serve hello-world
# 프로덕션 배포
supabase functions deploy hello-world
생성된 파일 구조는 supabase/functions/hello-world/index.ts이며, 진입점은 항상 Deno.serve 핸들러다.
Deno.serve(async (req: Request) => {
const { name } = await req.json()
return new Response(
JSON.stringify({ message: `Hello, ${name}!` }),
{ headers: { "Content-Type": "application/json" } }
)
})
외부 서비스(GitHub, Stripe 등)의 Webhook을 수신할 때 서명 검증이 필수다.
import { crypto } from "https://deno.land/std@0.177.0/crypto/mod.ts"
Deno.serve(async (req) => {
const signature = req.headers.get("stripe-signature") ?? ""
const body = await req.text()
const secret = Deno.env.get("STRIPE_WEBHOOK_SECRET")!
const isValid = await verifyStripeSignature(body, signature, secret)
if (!isValid) return new Response("Unauthorized", { status: 401 })
const event = JSON.parse(body)
// 이벤트 처리 로직
return new Response("ok")
})
Webhook 서명 검증 — 요청 본문과 타임스탬프를 HMAC-SHA256으로 해싱해 전송자의 신원을 확인하는 방식.
Edge Functions 내부에서 fetch를 직접 사용할 수 있다. OpenAI API 호출 예시는 다음과 같다.
Deno.serve(async (req) => {
const { prompt } = await req.json()
const response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${Deno.env.get("OPENAI_API_KEY")}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gpt-4o-mini",
messages: [{ role: "user", content: prompt }],
}),
})
const data = await response.json()
return new Response(JSON.stringify(data.choices[0].message))
})
환경 변수는 supabase secrets set KEY=value 명령으로 안전하게 주입한다.
pg_cron 확장과 결합하면 Edge Functions를 주기적으로 트리거할 수 있다.
-- 매일 자정에 Edge Function 호출
select cron.schedule(
'daily-cleanup',
'0 0 * * *',
$$
select net.http_post(
url := 'https://<project>.supabase.co/functions/v1/cleanup',
headers := '{"Authorization": "Bearer <anon-key>"}'::jsonb
)
$$
);
| 트리거 방식 | 사용 사례 |
|---|---|
| HTTP 요청 | Webhook, API 엔드포인트 |
| Database Webhook | 레코드 변경 시 알림 발송 |
| pg_cron | 정기 배치 작업 |
| Auth Hook | 회원가입 후처리 |
Edge Functions는 Supabase 프로젝트와 동일한 네트워크 내에서 실행되기 때문에 Service Role Key를 사용하면 RLS를 우회한 관리자 권한 DB 접근도 가능하다. 단, 이 키는 반드시 서버 사이드에서만 사용해야 한다.