Supabase는 PostgreSQL 테이블을 생성하는 순간 해당 테이블에 대한 REST API를 자동으로 노출한다. 별도의 Controller나 Route 정의 없이도 클라이언트에서 바로 HTTP 요청을 보낼 수 있다. 이 자동화의 핵심은 PostgREST라는 오픈소스 서버다.
Supabase의 API 레이어는 PostgREST가 PostgreSQL 스키마를 읽어 엔드포인트를 동적으로 생성하는 방식으로 동작한다.
PostgreSQL DB
│
▼
PostgREST ← 스키마 읽기 → REST 엔드포인트 자동 생성
│
▼
HTTP /rest/v1/{table}
│
▼
Client
PostgREST — PostgreSQL 데이터베이스를 REST API로 변환하는 오픈소스 미들웨어. Supabase는 이를 내장해 별도 서버 코드 없이 API를 제공한다.
public 스키마에 생성된 테이블은 즉시 /rest/v1/{테이블명} 경로로 접근 가능하다. Row Level Security(RLS)를 활성화하면 API Key와 정책에 따라 접근이 제어된다.
각 HTTP 메서드가 CRUD 동작에 대응한다.
const BASE = "https://<project>.supabase.co/rest/v1";
const HEADERS = {
apikey: process.env.SUPABASE_ANON_KEY!,
Authorization: `Bearer ${process.env.SUPABASE_ANON_KEY!}`,
"Content-Type": "application/json",
};
// READ
const res = await fetch(`${BASE}/posts?select=id,title`, { headers: HEADERS });
// CREATE
await fetch(`${BASE}/posts`, {
method: "POST",
headers: { ...HEADERS, Prefer: "return=representation" },
body: JSON.stringify({ title: "Hello", body: "World" }),
});
// UPDATE
await fetch(`${BASE}/posts?id=eq.1`, {
method: "PATCH",
headers: HEADERS,
body: JSON.stringify({ title: "Updated" }),
});
// DELETE
await fetch(`${BASE}/posts?id=eq.1`, { method: "DELETE", headers: HEADERS });
Prefer: return=representation — 삽입/수정 후 변경된 행을 응답 본문에 포함하도록 PostgREST에 지시하는 헤더.
쿼리 파라미터만으로 복잡한 조건을 표현할 수 있다.
| 기능 | 파라미터 예시 |
|---|---|
| 필터 | ?status=eq.published |
| 범위 필터 | ?created_at=gte.2026-01-01 |
| 정렬 | ?order=created_at.desc |
| 페이지네이션 | ?limit=10&offset=20 |
| 컬럼 선택 | ?select=id,title,author(name) |
관계형 조인도 select=posts(*,author:profiles(name))처럼 중첩 선택으로 한 번에 처리할 수 있다.
API 요청에는 반드시 API Key가 필요하며, 두 종류의 키가 목적에 따라 구분된다.
anon key
└─ 브라우저/앱에 노출 가능
└─ RLS 정책의 적용을 받음
└─ 익명 사용자 또는 JWT로 인증된 사용자 권한
service role key
└─ 서버(백엔드)에서만 사용
└─ RLS를 우회하여 모든 행에 접근
└─ 절대 클라이언트에 노출 금지
RLS (Row Level Security) — PostgreSQL의 행 단위 접근 제어 기능. Supabase에서는 RLS 정책을 통해 anon key 요청의 데이터 범위를 제한한다.
service role key가 클라이언트에 노출되면 RLS가 무력화되어 전체 데이터가 위험에 노출된다. 환경 변수는 서버 사이드에서만 참조해야 한다.
# .env.local (Next.js 서버 컴포넌트 전용)
SUPABASE_SERVICE_ROLE_KEY=eyJ...
# 클라이언트에서 접근 가능한 변수 (NEXT_PUBLIC_ 접두사)
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
Supabase REST API는 별도의 백엔드 없이 프론트엔드에서 직접 데이터베이스를 다룰 수 있는 가장 빠른 경로다. RLS 정책을 올바르게 설정하는 것이 보안의 전부다.