개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Supabase JavaScript Client — SDK로 데이터베이스 조작

2025년 4월 10일
SupabaseJavaScript Clientsupabase-jsselectinsert

Supabase는 PostgreSQL을 백엔드로 사용하면서도 REST API와 Realtime 구독을 기본 제공한다. supabase-js는 이 모든 기능을 브라우저와 Node.js 환경에서 동일한 인터페이스로 사용할 수 있게 해주는 공식 JavaScript SDK다. 별도의 ORM 없이 타입 안전한 쿼리 빌더를 체이닝 방식으로 구성할 수 있어 개발 속도가 빠르다.

createClient 초기화

프로젝트 URL과 anon 키만 있으면 클라이언트를 생성할 수 있다.

import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)

anon key — Row Level Security(RLS)가 적용된 상태에서 인증되지 않은 사용자에게 허용되는 공개 키. 클라이언트 번들에 포함되어도 안전하다.

데이터 조회 — select

// 전체 컬럼 조회
const { data, error } = await supabase
  .from('posts')
  .select('*')

// 특정 컬럼 + 필터 체이닝
const { data } = await supabase
  .from('posts')
  .select('id, title, created_at')
  .eq('category', 'database')
  .order('created_at', { ascending: false })
  .limit(10)

필터 체이닝은 메서드를 순서대로 연결하는 방식으로, 내부적으로 PostgREST 쿼리 파라미터로 변환된다. eq, neq, gt, lt, like, in 등 PostgreSQL 연산자 대부분을 지원한다.

데이터 삽입 / 수정 / 삭제

// insert
const { data, error } = await supabase
  .from('posts')
  .insert({ title: '새 글', category: 'database' })
  .select()

// update
await supabase
  .from('posts')
  .update({ title: '수정된 글' })
  .eq('id', 42)

// delete
await supabase
  .from('posts')
  .delete()
  .eq('id', 42)

insert 뒤에 .select를 체이닝하면 삽입된 행을 즉시 반환받을 수 있다. update와 delete는 반드시 필터 조건을 붙여야 한다. 조건 없이 호출하면 테이블 전체에 적용된다.

rpc — PostgreSQL 함수 호출

const { data } = await supabase
  .rpc('get_popular_posts', { min_views: 100 })

rpc — Remote Procedure Call. Supabase에서는 PostgreSQL 저장 함수(stored function)를 HTTP 엔드포인트로 노출하며, rpc로 호출한다.

복잡한 집계나 트랜잭션 로직은 PostgreSQL 함수로 작성하고 rpc로 호출하는 패턴이 권장된다.

auth / storage 메서드

// 이메일 로그인
const { data, error } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'secret',
})

// 파일 업로드
const { data } = await supabase.storage
  .from('avatars')
  .upload('public/avatar.png', file, { upsert: true })

supabase.auth와 supabase.storage는 동일한 클라이언트 인스턴스에서 접근한다. 로그인 후 세션은 자동으로 관리되며, 이후 .from 쿼리에 JWT가 자동 첨부된다.

클라이언트 데이터 흐름

Browser / Node.js
      |
  createClient()
      |
  ┌───┴──────────────────────────┐
  │  supabase-js SDK             │
  │  .from().select()  → REST    │
  │  .auth.*           → GoTrue  │
  │  .storage.*        → S3-like │
  │  .rpc()            → REST    │
  └───────────────────┬──────────┘
                      |
              Supabase Cloud
              (PostgreSQL + PostgREST)

하나의 supabase 인스턴스가 DB 쿼리, 인증, 파일 스토리지를 모두 처리한다. 각 요청은 내부적으로 HTTP 또는 WebSocket으로 변환되어 Supabase 백엔드로 전달된다.

에러 처리 패턴

모든 메서드는 { data, error } 구조를 반환한다. error가 null이 아니면 실패다.

const { data, error } = await supabase.from('posts').select('*')

if (error) {
  console.error(error.message)
  throw error
}

// data는 여기서 null이 아님이 보장됨

예외를 throw하는 대신 결과 객체를 반환하는 방식이므로, try/catch 없이도 명시적인 에러 분기가 가능하다.

← 이전 글Supabase Authorization — 권한 기반 접근 제어
다음 글 →Supabase REST API — 테이블에서 자동 생성되는 API