stack-analysis
CHAPTER 44 / 90
읽기 약 2분
FUNCTION
Supabase Edge Functions + Realtime
핵심 개념
Edge Functions·RLS·Realtime 구독·Storage — 풀스택 BaaS 활용.
본문
Edge Functions (Deno)
// supabase/functions/send-welcome/index.ts
import { serve } from 'https://deno.land/std/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
serve(async (req) => {
const { email, name } = await req.json();
const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!,
);
// Resend로 이메일 발송
const res = 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: email,
subject: `${name}님 환영합니다`,
html: '<h1>가입 완료</h1>',
}),
});
await supabase.from('email_logs').insert({
type: 'welcome', recipient: email, status: res.ok ? 'sent' : 'failed',
});
return new Response(JSON.stringify({ ok: res.ok }), {
headers: { 'Content-Type': 'application/json' },
});
});
// 배포
supabase functions deploy send-welcomeDatabase Webhook 트리거
-- 새 user 가입 시 자동 호출
CREATE OR REPLACE FUNCTION notify_user_signup()
RETURNS trigger AS $$
BEGIN
PERFORM net.http_post(
'https://<project>.functions.supabase.co/send-welcome',
jsonb_build_object('email', NEW.email, 'name', NEW.raw_user_meta_data->>'name'),
headers => jsonb_build_object('Authorization', 'Bearer ...')
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER on_user_signup
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION notify_user_signup();RLS (Row Level Security)
-- 사용자는 자기 게시물만 보기
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users see own posts"
ON posts FOR SELECT
USING (author_id = auth.uid());
CREATE POLICY "Users insert own posts"
ON posts FOR INSERT
WITH CHECK (author_id = auth.uid());
CREATE POLICY "Users update own posts"
ON posts FOR UPDATE
USING (author_id = auth.uid());
CREATE POLICY "Public read published"
ON posts FOR SELECT
USING (published = true);Realtime 구독
// 클라이언트
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(URL, ANON_KEY);
// 새 메시지 실시간 구독
const channel = supabase
.channel('room:123')
.on('postgres_changes', {
event: 'INSERT',
schema: 'public',
table: 'messages',
filter: 'room_id=eq.123',
}, (payload) => {
console.log('New message:', payload.new);
setMessages(prev => [...prev, payload.new]);
})
.subscribe();
// 정리
return () => { supabase.removeChannel(channel); };Presence (실시간 온라인 상태)
const channel = supabase.channel('online-users', {
config: { presence: { key: userId } },
});
channel
.on('presence', { event: 'sync' }, () => {
const state = channel.presenceState();
setOnlineUsers(Object.keys(state));
})
.subscribe(async (status) => {
if (status === 'SUBSCRIBED') {
await channel.track({ userId, online_at: new Date().toISOString() });
}
});Storage
// 업로드 (RLS 적용)
const file = event.target.files![0];
const path = `${userId}/${Date.now()}_${file.name}`;
const { data, error } = await supabase.storage
.from('avatars')
.upload(path, file, {
cacheControl: '3600',
upsert: false,
});
const { data: { publicUrl } } = supabase.storage
.from('avatars')
.getPublicUrl(path);
// Storage RLS
CREATE POLICY "Users upload own avatar"
ON storage.objects FOR INSERT
WITH CHECK (
bucket_id = 'avatars' AND
(storage.foldername(name))[1] = auth.uid()::text
);비용 효율 — 무료 한도
Free Tier:
- DB: 500MB
- Auth: 50,000 MAU
- Storage: 1GB
- Edge Functions: 500K invocations/mo
- Realtime: 200 동시 연결
Pro ($25/mo):
- DB: 8GB + 자동 백업
- Auth: 100K MAU
- Storage: 100GB
- Edge Functions: 2M invocations
- Realtime: 500 동시 연결
→ MVP·소규모는 Free, 100K MAU 도달 시 Pro 검토다음 챕터
CH.45 "DB 설계: 정규화 vs 비정규화 판단".
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 코드의 Supabase 활용 부분을 분석해서 실전 분석 + 개선 우선순위를 알려줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
Supabase 활용 관련 인기 라이브러리/패턴 5개를 비교 분석해서 패턴 추출를 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 프로젝트 전체에서 Supabase 활용 최적화 가능 위치를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 한국 백엔드 시장의 Supabase 활용 트렌드를 솔직히 알려줘.
⭐ 이것만 기억하세요
Supabase Edge Functions + Realtime는 이 3가지만 확실히 잡으세요
1.Edge Functions = Deno 기반 서버리스 — DB 트리거와 결합
2.RLS (Row Level Security)로 DB 레벨 권한 — 백엔드 코드 없이도 안전
3.Realtime + Presence = WebSocket 무료 — 채팅·온라인 표시
공유하기
진행도 44 / 90