OPEN HYPER STEP
← 목록으로 (stack-analysis)
STACK-ANALYSIS · 44 / 90
stack-analysis
CHAPTER 44 / 90
읽기 약 2
FUNCTION

Supabase Edge Functions + Realtime


핵심 개념

Edge Functions·RLS·Realtime 구독·Storage — 풀스택 BaaS 활용.

본문

Edge Functions (Deno)

TYPESCRIPT📋 코드 (39줄)
// 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-welcome

Database Webhook 트리거

SQL📋 코드 (16줄)
-- 새 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)

SQL📋 코드 (18줄)
-- 사용자는 자기 게시물만 보기
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 구독

TYPESCRIPT📋 코드 (22줄)
// 클라이언트
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 (실시간 온라인 상태)

TYPESCRIPT📋 코드 (14줄)
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

TYPESCRIPT📋 코드 (23줄)
// 업로드 (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
);

비용 효율 — 무료 한도

📋 코드 (17줄)
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