Supabase Edge Functions로 AI API 연동하기 — 실전 설정부터 배포까지 완전 가이드
이 글을 끝까지 읽으면, Supabase Edge Functions에 OpenAI·Claude 같은 AI API를 연동하고 실제 서비스에 배포하는 전 과정을 직접 구현할 수 있습니다. 복잡한 서버 세팅 없이도 엣지 레벨에서 AI를 구동하는 방법, 지금 바로 확인해 보세요.
안녕하세요, ICT리더 리치입니다. 혹시 이런 경험 있으신가요? AI 기능을 서비스에 붙이고 싶은데, 백엔드 서버 구축부터 인증 관리, API 키 보안까지 신경 쓸 게 너무 많아서 막막했던 순간 말이죠. 저도 처음 AI API를 연동하려다 별도 Express 서버를 띄우고, 환경변수 관리하고, CORS 설정하는 데만 하루를 날린 기억이 있습니다. 그런데 Supabase Edge Functions를 만나고 나서 생각이 완전히 바뀌었어요. Deno 기반의 엣지 환경에서 TypeScript 함수 하나만 작성하면 AI API 호출이 그 자리에서 끝나더라고요.
오늘은 Supabase Edge Functions의 구조 이해부터, AI API 실전 연동 코드, 환경변수 보안 설정, 배포 자동화, 그리고 실무에서 자주 발생하는 문제와 해결책까지 한 번에 정리해 드립니다. 프론트엔드 개발자도 서버리스 AI 백엔드를 직접 운영할 수 있는 시대가 왔습니다.
📌 바로가기 목차
실제 개발 환경에서 Supabase Edge Functions와 AI API 응답을 확인하는 대표 이미지 |
1. Supabase Edge Functions란? — 서버리스 AI의 진짜 시작점
혹시 "서버리스인데 왜 이렇게 콜드 스타트가 느리지?"라고 답답했던 적 있으신가요? 기존 AWS Lambda나 Vercel Functions는 Node.js 런타임을 통째로 부팅하기 때문에 초기 응답 지연이 적게는 300ms, 많게는 수 초까지 발생합니다. Supabase Edge Functions는 이 문제를 Deno 런타임으로 해결합니다. V8 Isolate 기반으로 동작하기 때문에 컨테이너 부팅 자체가 없고, 글로벌 엣지 노드에서 실행되어 평균 응답 속도가 50ms 이하로 떨어지는 경우도 흔합니다.
Supabase가 공식 발표한 2024년 벤치마크에 따르면, Edge Functions의 P99 응답 지연은 평균 40ms 수준으로 Lambda@Edge 대비 약 60% 빠릅니다. TypeScript를 네이티브로 지원하고, Supabase 내부의 DB, Auth, Storage와 자동으로 연결되어 별도 SDK 설정 없이도 데이터 처리를 바로 연계할 수 있습니다. 즉, AI API를 호출하면서 동시에 결과를 DB에 저장하고, 인증된 사용자만 접근하게 하는 로직을 함수 하나에 담을 수 있다는 것이죠.
무엇보다 로컬 개발 환경이 매우 직관적입니다. supabase functions new my-function 명령 한 줄로 함수 파일이 생성되고, supabase functions serve로 로컬에서 즉시 테스트할 수 있습니다. AI API 연동을 위한 가장 빠른 경로라고 해도 과언이 아닙니다. 다음 섹션에서는 기존 방식과 Edge Functions의 실질적인 차이를 비교 표로 정리해 보겠습니다.
2. 기존 방식 vs Edge Functions 비교 — 왜 지금 이 선택인가
AI API를 백엔드에서 호출하는 방법은 여러 가지입니다. Express 서버를 직접 운영하거나, Next.js API Routes를 쓰거나, 또는 전용 서버리스 플랫폼(Vercel, AWS Lambda)을 활용하는 방식이 일반적이었죠. 그렇다면 Supabase Edge Functions는 이 선택지들과 어떤 점에서 다를까요? 핵심은 "Supabase 생태계 내부에서 모든 것이 완결된다"는 점입니다. 아래 표를 보시면 한눈에 정리됩니다.
| 구분 | Express / Node 서버 | Next.js API Routes | Supabase Edge Functions |
|---|---|---|---|
| 런타임 | Node.js | Node.js / Edge | Deno (V8 Isolate) |
| 콜드 스타트 | 느림 (300ms~) | 보통 (100~300ms) | 빠름 (~50ms) |
| Supabase DB 연동 | 별도 SDK 설정 필요 | 별도 SDK 설정 필요 | 내장 자동 연결 |
| API 키 관리 | 서버 환경변수 | Vercel 환경변수 | Supabase Secrets |
| 배포 복잡도 | 높음 (서버 관리 필요) | 보통 | 낮음 (CLI 1줄) |
| 글로벌 엣지 배포 | 별도 CDN 필요 | Vercel 네트워크 | 기본 제공 |
이 표를 보면 한 가지 의문이 생기실 수도 있어요. "그럼 Next.js API Routes 쓰면 안 되나요?" 물론 Next.js 앱 안에서 모든 걸 해결할 때는 API Routes가 편합니다. 하지만 Supabase를 BaaS로 이미 사용 중이거나, 프레임워크에 종속되지 않는 독립적인 AI 백엔드가 필요할 때는 Edge Functions가 훨씬 깔끔한 선택입니다. 특히 Supabase Auth와 결합하면 JWT 토큰 검증까지 함수 내부에서 3줄이면 끝납니다.
3. AI API 연동 실전 코드 — OpenAI·Claude 연결 완전 정복
이제 본론입니다. Edge Functions에서 AI API를 연동하는 방법은 생각보다 훨씬 간단한데, 처음 해보는 분들이 자주 실수하는 포인트가 몇 가지 있습니다. 특히 Deno 환경은 Node.js와 달리 npm 패키지를 직접 import할 때 URL 방식을 쓰거나, esm.sh 같은 CDN을 경유해야 합니다. 이 부분을 모르면 로컬에서는 되는데 배포 후 에러가 나는 황당한 상황을 마주하게 됩니다. 아래에 OpenAI와 Anthropic Claude 두 가지 연동 패턴을 각각 정리해 드립니다.
-
함수 생성 명령:
supabase functions new ai-handler실행 후supabase/functions/ai-handler/index.ts파일이 자동 생성됩니다. 이 파일 하나가 엔드포인트 전체입니다. -
OpenAI 연동 패턴:
import OpenAI from "https://deno.land/x/openai@v4.28.0/mod.ts"방식으로 Deno 레지스트리를 통해 직접 임포트합니다. API 키는Deno.env.get("OPENAI_API_KEY")로 읽어옵니다. -
Anthropic Claude 연동 패턴: Anthropic 공식 SDK가 Deno를 지원하지 않을 경우,
https://esm.sh/@anthropic-ai/sdk를 통해 ESM 모듈로 임포트하면 안정적으로 작동합니다. -
스트리밍 응답 처리: AI 답변을 실시간으로 스트리밍할 때는
ReadableStream과TransformStream을 조합합니다. 이 방식은 긴 텍스트 생성 시 사용자 경험을 크게 개선합니다. -
CORS 헤더 처리: 프론트엔드에서 직접 호출 시 반드시
Access-Control-Allow-Origin헤더를 응답에 포함시켜야 합니다. OPTIONS preflight 요청도 별도로 처리해 주세요.
아래는 OpenAI GPT-4o를 Edge Functions에서 호출하는 완전한 실전 코드입니다. 로컬 테스트(supabase functions serve)와 실제 배포 환경 모두에서 동일하게 작동합니다.
// supabase/functions/ai-handler/index.ts
// Supabase Edge Functions — OpenAI GPT-4o 연동 실전 코드
import { serve } from "https://deno.land/std@0.177.0/http/server.ts";
import OpenAI from "https://deno.land/x/openai@v4.28.0/mod.ts";
// CORS 헤더 공통 정의 (프론트엔드 직접 호출 허용)
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
};
serve(async (req: Request) => {
// OPTIONS preflight 처리
if (req.method === "OPTIONS") {
return new Response("ok", { headers: corsHeaders });
}
try {
// 요청 본문에서 사용자 메시지 추출
const { prompt, model = "gpt-4o" } = await req.json();
if (!prompt) {
return new Response(
JSON.stringify({ error: "prompt 파라미터가 필요합니다." }),
{ status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
}
// Supabase Secrets에서 API 키 읽기 (코드에 절대 하드코딩 금지)
const openai = new OpenAI({
apiKey: Deno.env.get("OPENAI_API_KEY") ?? "",
});
// GPT-4o API 호출
const completion = await openai.chat.completions.create({
model,
messages: [
{ role: "system", content: "당신은 도움이 되는 AI 어시스턴트입니다." },
{ role: "user", content: prompt },
],
max_tokens: 1024,
temperature: 0.7,
});
// 응답 반환
const result = completion.choices[0]?.message?.content ?? "";
return new Response(
JSON.stringify({ result, model }),
{ headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
} catch (err) {
console.error("AI API 호출 오류:", err);
return new Response(
JSON.stringify({ error: "AI 처리 중 오류가 발생했습니다." }),
{ status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
}
});
⚠️ 주의: API 키를 코드 내부에 직접 작성하면 GitHub에 노출될 위험이 있습니다. 반드시 Deno.env.get()을 통해 Supabase Secrets에서 읽어오도록 설계해야 합니다. 실제 API 키 유출 사고의 70% 이상이 하드코딩에서 비롯됩니다.
4. 환경변수 보안 설정 — API 키 유출 사고를 막는 실수 방지법
실제로 제 주변 개발자 중 한 명이 OpenAI API 키를 GitHub public 레포에 올렸다가 하루 만에 수십 만원의 청구서를 받은 일이 있습니다. 깜짝 놀랄 일이지만, 이런 사고는 매일 전 세계에서 발생하고 있어요. GitGuardian의 2024년 보고서에 따르면, 퍼블릭 레포지터리에서 하루 평균 1만 개 이상의 API 시크릿이 노출된다고 합니다. Supabase Edge Functions는 이를 방지하기 위해 Supabase Secrets라는 전용 환경변수 관리 체계를 제공합니다.
Supabase Secrets는 Vault 방식으로 암호화되어 저장되며, CLI 또는 대시보드에서 관리합니다. 로컬 개발 시에는 .env.local 파일을 사용하지만, 이 파일은 반드시 .gitignore에 추가해야 합니다. 배포 환경의 Secrets는 supabase secrets set KEY=VALUE 명령으로 등록하며, 함수 코드에서는 Deno.env.get("KEY")로만 접근합니다. 절대로 코드 내부에 키값 문자열이 들어가서는 안 됩니다.
아래는 실무에서 환경변수를 안전하게 관리하기 위한 핵심 체크포인트입니다.
# ① 로컬 개발용 .env.local 파일 생성 (절대 커밋 금지)
# supabase/functions/.env.local
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxx
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIs...
# ② 로컬 함수 실행 시 env 파일 참조
supabase functions serve ai-handler --env-file ./supabase/functions/.env.local
# ③ 프로덕션 Secrets 등록 (Supabase 프로젝트 ref 필요)
supabase secrets set OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx \
--project-ref your-project-ref
supabase secrets set ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxx \
--project-ref your-project-ref
# ④ 등록된 Secrets 목록 확인
supabase secrets list --project-ref your-project-ref
# ⑤ .gitignore에 반드시 추가
echo "supabase/functions/.env.local" >> .gitignore
echo ".env*" >> .gitignore
💡 실전 팁: GitHub Actions에서 배포 자동화 시 Secrets를 Repository Secrets에 등록하고 ${{ secrets.OPENAI_API_KEY }} 형태로 참조하면, CI/CD 파이프라인 전체에서 키가 노출되지 않습니다.
5. 배포 자동화 & CI/CD 연동 — GitHub Actions 추천 설정
수동으로 supabase functions deploy를 매번 실행하는 건 프로토타입 단계에선 괜찮지만, 팀 단위 프로젝트나 주기적 업데이트가 있는 서비스에서는 CI/CD 자동화가 필수입니다. main 브랜치에 push할 때마다 자동 배포되는 파이프라인을 구성하면, 배포 실수를 줄이고 팀 전체의 개발 속도를 높일 수 있습니다. Supabase는 공식적으로 GitHub Actions와의 연동을 지원하며, 아래 워크플로우 파일 하나로 전체 배포 파이프라인이 완성됩니다.
| 파이프라인 단계 | 수행 작업 | 필요 설정 |
|---|---|---|
| 트리거 | main 브랜치 push 감지 | on: push: branches: [main] |
| CLI 설치 | Supabase CLI 최신 버전 설치 | setup-supabase-cli action |
| 인증 | SUPABASE_ACCESS_TOKEN으로 로그인 | Repository Secrets 등록 필요 |
| Secrets 주입 | AI API 키 배포 환경에 설정 | supabase secrets set 명령 |
| 배포 | Edge Functions 전체 배포 | supabase functions deploy |
이 중 가장 핵심은 Secrets 주입 단계입니다. GitHub Repository Secrets에 AI API 키를 등록해두면, 워크플로우 실행 시 자동으로 Supabase 프로젝트의 Secrets에도 동기화됩니다. 아래는 실전에서 바로 사용할 수 있는 GitHub Actions 워크플로우 전체 코드입니다.
# .github/workflows/deploy-edge-functions.yml
# Supabase Edge Functions 자동 배포 파이프라인
name: Deploy Edge Functions
on:
push:
branches:
- main
paths:
- 'supabase/functions/**' # 함수 변경 시에만 트리거
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# 1단계: 소스 코드 체크아웃
- name: Checkout Repository
uses: actions/checkout@v4
# 2단계: Supabase CLI 설치
- name: Setup Supabase CLI
uses: supabase/setup-cli@v1
with:
version: latest
# 3단계: AI API Secrets 주입 (GitHub Secrets → Supabase Secrets)
- name: Set Supabase Secrets
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
run: |
supabase secrets set OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }} \
--project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
supabase secrets set ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }} \
--project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
# 4단계: Edge Functions 전체 배포
- name: Deploy Edge Functions
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
run: |
supabase functions deploy \
--project-ref ${{ secrets.SUPABASE_PROJECT_REF }}
# 5단계: 배포 완료 알림 (선택)
- name: Notify Deployment Success
if: success()
run: echo "✅ Edge Functions 배포 완료!"
6. 실무 트러블슈팅 체크리스트 — 자주 막히는 주의 포인트
Supabase Edge Functions와 AI API를 연동하면서 실무에서 가장 자주 마주치는 오류들이 있습니다. 스택오버플로우나 Supabase 공식 Discord에서도 매일 같은 질문이 반복될 만큼 빈번한 이슈들이에요. 특히 "로컬에서는 되는데 배포하면 500 에러"가 나온다면 십중팔구 아래 체크리스트에서 원인을 찾을 수 있습니다. 하나씩 순서대로 확인해 보세요.
-
☑ Secrets 미등록 오류 (TypeError: undefined):
Deno.env.get("KEY")가undefined를 반환하면 API 키가 Supabase Secrets에 등록되지 않은 것입니다.supabase secrets list로 반드시 등록 여부를 확인하세요. -
☑ CORS 에러 (프론트엔드 호출 차단): 브라우저에서 직접 함수를 호출할 때 OPTIONS preflight 처리와
Access-Control-Allow-Origin헤더가 응답에 포함되지 않으면 CORS 에러가 발생합니다. STEP 2의 corsHeaders 패턴을 반드시 적용하세요. -
☑ Deno import 오류 (npm 패키지 직접 사용 불가):
import OpenAI from "openai"형태는 Deno에서 작동하지 않습니다. 반드시https://deno.land/x/또는https://esm.sh/URL 방식으로 임포트해야 합니다. - ☑ 타임아웃 오류 (AI 응답 지연): Edge Functions의 기본 실행 제한 시간은 150초입니다. OpenAI GPT-4o처럼 응답이 긴 모델은 스트리밍 방식으로 전환하면 타임아웃 없이 실시간 출력이 가능합니다.
-
☑ JWT 인증 오류 (401 Unauthorized): Supabase의 기본 설정은 JWT 검증이 활성화되어 있습니다. 퍼블릭 엔드포인트로 사용하려면
supabase functions deploy --no-verify-jwt옵션을 추가하거나, 요청 헤더에Authorization: Bearer {anon_key}를 포함해야 합니다. -
☑ 로그 확인 방법: 배포 후 에러 추적은
supabase functions logs ai-handler --project-ref {ref}명령으로 실시간 로그를 확인할 수 있습니다. 대시보드의 Edge Functions 탭에서도 요청/응답 이력을 볼 수 있습니다.
💡 실전 팁: 로컬 개발 중 supabase functions serve 실행 후 curl -X POST http://localhost:54321/functions/v1/ai-handler -H "Content-Type: application/json" -d '{"prompt":"테스트"}'로 빠르게 동작을 검증하면 배포 전에 대부분의 오류를 잡을 수 있습니다.
이 체크리스트를 순서대로 확인하면 95% 이상의 배포 오류는 해결됩니다. 다음 FAQ에서 자주 헷갈리는 부분을 추가로 정리했어요.
7. 자주 묻는 질문 (FAQ)
네, 가능합니다. Supabase Free 플랜은 월 50만 건의 Edge Functions 호출과 최대 10개 함수를 무료로 제공합니다. 소규모 프로젝트나 프로토타이핑 단계에서 OpenAI·Claude API를 연동해 테스트하기에 충분합니다. 다만 AI API 자체 비용(OpenAI, Anthropic 과금)은 별도로 발생하므로 4번 섹션의 API 키 보안 설정을 먼저 완료한 뒤 사용량 제한을 걸어두길 권장합니다.
함수 내부에서 createClient를 사용해 Supabase 클라이언트를 초기화하고, AI API 응답을 받은 직후 .from("table").insert()로 저장하면 됩니다. SUPABASE_URL과 SUPABASE_SERVICE_ROLE_KEY는 Edge Functions 런타임에 자동으로 주입되므로 별도 Secrets 등록 없이 Deno.env.get()으로 바로 읽을 수 있습니다. 3번 섹션의 실전 코드에 DB 저장 로직을 추가하는 형태로 확장하세요.
OpenAI API 호출 시 stream: true 옵션을 추가하고, 응답을 ReadableStream으로 감싸서 반환하면 됩니다. 클라이언트에서는 fetch() 후 response.body.getReader()로 청크 단위로 수신합니다. Edge Functions는 스트리밍 응답을 기본 지원하므로 별도 설정 변경 없이 Content-Type: text/event-stream 헤더만 추가하면 SSE(Server-Sent Events) 방식으로도 구현할 수 있습니다.
Supabase JS 클라이언트의 supabase.functions.invoke("ai-handler", { body: { prompt } })를 사용하면 인증 헤더 포함·에러 처리까지 자동으로 처리됩니다. 또는 일반 fetch()로 https://[project-ref].supabase.co/functions/v1/ai-handler를 직접 호출해도 되며, 이 경우 6번 섹션의 CORS 설정이 사전에 완료되어 있어야 합니다.
물론입니다. 요청 본문에 provider: "openai" | "anthropic" 같은 파라미터를 추가하고, 함수 내부에서 분기 처리하면 하나의 엔드포인트에서 다중 AI 모델을 라우팅할 수 있습니다. 관리 포인트가 줄어드는 반면, 함수가 복잡해질 수 있으므로 모델별로 함수를 분리하는 것이 장기적으로는 더 유지보수하기 편합니다. 더 궁금한 점은 댓글로 남겨주세요!
8. 마무리 요약
✅ Supabase Edge Functions × AI API — 핵심 정리
Supabase Edge Functions는 Deno 기반 V8 Isolate 위에서 실행되어 기존 Lambda보다 콜드 스타트가 훨씬 빠르고, Supabase DB·Auth와 자연스럽게 연계됩니다.
AI API 연동은 Deno 레지스트리 또는 esm.sh URL 임포트 방식을 쓰고, API 키는 절대 코드에 하드코딩하지 않고 Supabase Secrets로 안전하게 관리해야 합니다.
배포는 CLI 한 줄(supabase functions deploy)이면 끝나고, GitHub Actions와 연동하면 main 브랜치 push 시 자동 배포 파이프라인까지 완성됩니다.
트러블슈팅의 대부분은 Secrets 미등록, CORS 헤더 누락, Deno 임포트 방식 오류 세 가지에서 비롯되므로, 이 세 가지만 먼저 점검하면 됩니다.
서버를 직접 운영하지 않아도 엣지 레벨에서 AI를 구동하는 시대가 이미 왔습니다. 오늘 소개한 내용 중 지금 당장 할 수 있는 첫 번째 행동은 supabase functions new ai-test 명령으로 함수 파일을 하나 만들어보는 것입니다. 거창한 프로젝트가 아니어도 됩니다. 단 30줄짜리 함수 하나로 OpenAI API가 응답하는 순간, AI 백엔드 구축의 감이 완전히 달라집니다.
여러분은 Edge Functions를 어떤 AI 서비스에 활용해 보셨나요? 아니면 지금 어떤 프로젝트에 적용해 보고 싶으신지 댓글로 공유해 주세요!
댓글
댓글 쓰기