Contents
see List개요
Supabase Edge Functions는 Deno 런타임 기반으로 동작하는 서버리스 함수로, Vercel의 Edge Functions나 Cloudflare Workers와 유사한 개념입니다. 전 세계에 분산된 엣지 로케이션에서 실행되어 낮은 지연시간과 빠른 응답 속도를 제공하며, PostgreSQL 데이터베이스와의 긴밀한 통합을 통해 백엔드 로직을 효율적으로 구현할 수 있습니다.
이 글에서는 Edge Functions의 핵심 개념부터 실전 활용 사례, 성능 최적화 팁까지 살펴보겠습니다.
핵심 개념
1. Deno 런타임
Edge Functions는 Node.js가 아닌 Deno 런타임에서 실행됩니다. TypeScript를 네이티브로 지원하며, Web API 표준을 따르기 때문에 fetch, Request, Response 등의 표준 API를 그대로 사용할 수 있습니다.
2. 자동 스케일링
트래픽에 따라 자동으로 스케일업/다운되며, 콜드 스타트 시간이 매우 짧습니다(약 50-100ms). 사용량 기반 과금으로 비용 효율적입니다.
3. Database 직접 연결
Supabase 클라이언트를 통해 PostgreSQL 데이터베이스에 직접 접근할 수 있으며, Row Level Security(RLS) 정책도 자동으로 적용됩니다.
실전 예제
기본 Edge Function 구조
// supabase/functions/hello-world/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) => {
try {
// CORS 헤더 설정
if (req.method === 'OPTIONS') {
return new Response('ok', {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
}
})
}
// Supabase 클라이언트 생성
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_ANON_KEY') ?? '',
{
global: {
headers: { Authorization: req.headers.get('Authorization')! },
},
}
)
// 데이터베이스 조회
const { data, error } = await supabase
.from('posts')
.select('*')
.limit(10)
if (error) throw error
return new Response(
JSON.stringify({ data }),
{
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
}
}
)
} catch (error) {
return new Response(
JSON.stringify({ error: error.message }),
{
status: 400,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
}
}
)
}
})
파일 업로드 처리
// supabase/functions/upload-image/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') ?? ''
)
// FormData 파싱
const formData = await req.formData()
const file = formData.get('file') as File
if (!file) {
return new Response(
JSON.stringify({ error: 'No file provided' }),
{ status: 400, headers: { 'Content-Type': 'application/json' } }
)
}
// Storage에 업로드
const fileName = `${Date.now()}-${file.name}`
const { data, error } = await supabase.storage
.from('images')
.upload(fileName, file, {
contentType: file.type,
cacheControl: '3600'
})
if (error) throw error
// Public URL 생성
const { data: { publicUrl } } = supabase.storage
.from('images')
.getPublicUrl(fileName)
return new Response(
JSON.stringify({ url: publicUrl }),
{ headers: { 'Content-Type': 'application/json' } }
)
})
외부 API 통합
// supabase/functions/send-notification/index.ts
serve(async (req) => {
const { message, userId } = await req.json()
// Slack Webhook 호출
const slackResponse = await fetch(Deno.env.get('SLACK_WEBHOOK_URL')!, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `New message from user ${userId}: ${message}`
})
})
// 데이터베이스에 알림 로그 저장
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
)
await supabase
.from('notifications')
.insert({ user_id: userId, message, sent_at: new Date().toISOString() })
return new Response(
JSON.stringify({ success: true }),
{ headers: { 'Content-Type': 'application/json' } }
)
})
활용 팁
- 환경 변수 관리: Supabase 대시보드에서 Edge Functions Secrets를 설정하면 Deno.env.get()으로 접근 가능합니다. API 키나 토큰은 반드시 Secrets로 관리하세요.
- 로컬 개발:
supabase functions serve명령으로 로컬에서 테스트할 수 있습니다. Docker가 필요합니다. - 배포:
supabase functions deploy function-name로 배포하며, 자동으로 HTTPS 엔드포인트가 생성됩니다. - 성능 최적화: 데이터베이스 커넥션은 함수 호출마다 새로 생성되므로, 가능한 한 적은 쿼리로 데이터를 가져오세요. Supabase 클라이언트의 select() 체이닝을 적극 활용하세요.
- 에러 핸들링: try-catch로 모든 비동기 작업을 감싸고, 명확한 에러 메시지와 HTTP 상태 코드를 반환하세요.
- CORS 설정: 브라우저에서 호출할 경우 OPTIONS 메서드 처리와 Access-Control-Allow-Origin 헤더 설정이 필수입니다.
- 인증: RLS를 활용하려면 클라이언트의 Authorization 헤더를 Edge Function으로 전달해야 합니다.
마무리
Supabase Edge Functions는 서버리스 아키텍처의 장점과 PostgreSQL의 강력한 기능을 결합하여, 복잡한 백엔드 로직을 간단하게 구현할 수 있게 해줍니다. 특히 파일 처리, 외부 API 통합, 복잡한 비즈니스 로직 등 클라이언트에서 직접 처리하기 어려운 작업에 적합합니다.
Deno 런타임의 보안성과 TypeScript 네이티브 지원, 그리고 전 세계 엣지 로케이션 배포를 통해 빠르고 안전한 API를 구축할 수 있습니다. 다음 프로젝트에서 Edge Functions를 활용해보시기 바랍니다.