supabase

Supabase 사용해 보기

Supabase 사용해 보기
0 views
views
10 min read
#supabase

Supabase는 Firebase의 오픈 소스 대안으로 주목받는 BaaS(Backend as a Service) 플랫폼입니다.
PostgreSQL 데이터베이스를 기반으로 인증, 스토리지, 서버리스 함수 등 다양한 기능을 제공합니다.
이번 글에서는 Supabase를 시작하는 방법부터 간단한 인증, 데이터베이스 연동, 스토리지 사용 예시까지 살펴보겠습니다.


1. Supabase 소개

1.1 특징

  • 오픈 소스: 핵심 서비스가 오픈 소스로 제공되어 투명성과 확장성이 뛰어남
  • PostgreSQL 기반: 강력하고 안정적인 PostgreSQL 데이터베이스 활용
  • 자동 API 생성: 테이블 생성 시 즉시 RESTful API 사용 가능
  • 인증/스토리지 제공: Firebase와 유사하게 인증, 스토리지, 서버리스 함수(Function)를 제공

1.2 Firebase와의 차이점

  • 라이선스: Firebase는 Google에서 제공하지만, Supabase는 오픈 소스로 누구나 기여 가능
  • 데이터베이스: Firebase Realtime Database / Firestore와 달리 SQL 기반 PostgreSQL 사용
  • 배포 방식: 커뮤니티 에디션을 자체 호스팅하거나, Supabase에서 제공하는 호스팅을 이용할 수 있음

2. 프로젝트 시작하기

2.1 프로젝트 생성

먼저 Supabase 공식 사이트에서 계정을 생성한 뒤 프로젝트를 생성합니다.

  1. 프로젝트 이름 지정
  2. 지역(Region) 선택
  3. 비밀번호 설정
  4. 프로젝트가 생성되면, API URLanon/public 키와 같은 인증 정보를 발급받을 수 있습니다.

2.2 Supabase CLI 설치 (선택)

Supabase CLI를 이용하면 로컬에서 간단히 Supabase 프로젝트를 관리할 수 있습니다.
아래와 같이 CLI를 설치해 사용해볼 수 있습니다.

npm install supabase --global

설치 후 supabase --version 명령어로 설치가 완료되었는지 확인합니다.


3. Next.js 프로젝트에 Supabase 연동하기

3.1 Next.js 프로젝트 생성

npx create-next-app my-supabase-app
cd my-supabase-app

프로젝트 생성 후 필요한 패키지를 설치합니다.

npm install @supabase/supabase-js

3.2 환경 변수 설정

.env.local 파일을 생성하고, Supabase에서 발급받은 API URLanon key를 다음과 같이 저장합니다:

NEXT_PUBLIC_SUPABASE_URL=<YOUR_SUPABASE_URL>
NEXT_PUBLIC_SUPABASE_ANON_KEY=<YOUR_SUPABASE_ANON_KEY>

3.3 Supabase Client 설정

공통으로 사용할 Supabase Client를 생성해봅니다.

lib/supabaseClient.ts
import { createClient } from '@supabase/supabase-js';
 
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
 
export const supabase = createClient(supabaseUrl, supabaseAnonKey);
  • supabaseUrl: Supabase 프로젝트의 URL
  • supabaseAnonKey: Supabase에서 발급받은 공개 키(anon key)
  • 위 코드를 기반으로 어디서든 supabase 객체를 import하여 사용할 수 있습니다.

4. 기본 기능 사용해 보기

4.1 인증(Authentication)

Supabase는 이메일/비밀번호, 소셜 로그인을 포함해 다양한 인증 방식을 제공합니다.

이메일/비밀번호 가입 예시

pages/auth.tsx
import React, { useState } from 'react';
import { supabase } from '../lib/supabaseClient';
 
export default function AuthPage() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
 
  const handleSignUp = async () => {
    const { user, error } = await supabase.auth.signUp({
      email,
      password,
    });
    if (error) {
      console.error('Sign up error: ', error.message);
    } else {
      console.log('Sign up success: ', user);
    }
  };
 
  return (
    <div>
      <h1>회원가입</h1>
      <input
        type="email"
        placeholder="이메일"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
      <input
        type="password"
        placeholder="비밀번호"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
      />
      <button onClick={handleSignUp}>가입하기</button>
    </div>
  );
}
  • supabase.auth.signUp() 메서드를 사용하여 이메일/비밀번호 가입을 수행합니다.
  • 가입이 완료되면, Supabase 콘솔에서 사용자를 확인할 수 있습니다.

4.2 데이터베이스(Database)

데이터 테이블 생성

  • Supabase 콘솔의 Table Editor에서 테이블을 생성합니다.
    • 예: todos 테이블
    • 컬럼: id(PK, auto-increment), title, is_complete(boolean)

데이터 삽입 및 조회

pages/todos.tsx
import React, { useEffect, useState } from 'react';
import { supabase } from '../lib/supabaseClient';
 
export default function Todos() {
  const [todos, setTodos] = useState([]);
 
  useEffect(() => {
    fetchTodos();
  }, []);
 
  const fetchTodos = async () => {
    const { data, error } = await supabase.from('todos').select('*');
    if (error) console.error('Error fetching todos:', error);
    else setTodos(data || []);
  };
 
  const addTodo = async () => {
    const { error } = await supabase.from('todos').insert({ title: 'New Task', is_complete: false });
    if (error) console.error('Error adding todo:', error);
    else fetchTodos();
  };
 
  return (
    <div>
      <h1>Todos</h1>
      <button onClick={addTodo}>할 일 추가</button>
      <ul>
        {todos.map((todo: any) => (
          <li key={todo.id}>
            {todo.title} - {todo.is_complete ? '완료' : '미완료'}
          </li>
        ))}
      </ul>
    </div>
  );
}
  • supabase.from('todos').select('*')로 todos 테이블의 모든 데이터를 조회
  • supabase.from('todos').insert()로 새 할 일(Task)을 추가
  • 에러가 없다면 상태를 갱신해 화면에 즉시 반영

4.3 스토리지(Storage)

사용자가 업로드하는 파일, 이미지 등을 저장할 수 있는 기능입니다.

  1. 스토리지 버킷 생성
    • Supabase 콘솔에서 Storage 메뉴 -> New Bucket 클릭 -> 버킷 이름 지정 (예: images)
  2. 클라이언트에서 업로드 예시
    pages/upload.tsx
    import React, { useState } from 'react';
    import { supabase } from '../lib/supabaseClient';
     
    export default function Upload() {
      const [selectedFile, setSelectedFile] = useState<File | null>(null);
     
      const handleUpload = async () => {
        if (!selectedFile) return;
        const { data, error } = await supabase.storage
          .from('images')
          .upload(`public/${selectedFile.name}`, selectedFile, {
            upsert: true,
          });
        if (error) console.error('Upload error: ', error.message);
        else console.log('Upload success: ', data);
      };
     
      return (
        <div>
          <h1>이미지 업로드</h1>
          <input
            type="file"
            onChange={(e) => setSelectedFile(e.target.files?.[0] || null)}
          />
          <button onClick={handleUpload}>업로드하기</button>
        </div>
      );
    }
    • supabase.storage.from('images')images 버킷을 참조
    • 파일 업로드가 성공하면 해당 파일 경로를 반환

5. 서버리스 함수(Function) 사용 (선택)

Supabase는 서버리스 함수를 통해 다양한 백엔드 로직을 구현할 수 있습니다.
커스텀 API를 만들거나, Cron Job 등을 설정할 수 있습니다.
다만 서버리스 함수는 현재 베타 기능이므로, 실제 서비스에 도입하기 전 테스트와 안정성 검증이 필요합니다.


6. 디버깅 & 문제 해결

  1. 인증 문제가 발생할 때

    • Supabase 콘솔에서 인증 방식이 활성화되어 있는지 확인(소셜 로그인, 이메일 인증 등)
    • supabase.auth 관련 API 키와 URL 설정이 올바른지 재확인
  2. CORS 에러

    • 프로젝트 설정에서 Allowed Origins(CORS) 항목에 해당 도메인을 추가
  3. 데이터베이스 쿼리 에러

    • 콘솔의 Table Editor 혹은 SQL Editor에서 쿼리를 직접 테스트해보기
    • 테이블 권한 설정(RLS: Row Level Security)이 활성화되어 있어 발생할 수 있으므로 권한 정책을 확인

7. Supabase를 실제 서비스에 적용할 때 고려 사항

  • 비용: 무료 플랜이 존재하지만, 데이터베이스 사용량이 늘어나면 비용이 발생할 수 있음
  • 확장성: 프로젝트 규모가 커질수록 자체 호스팅 방안도 고민해야 함 (스스로 서버 리소스 확보)
  • RLS(Row Level Security): Supabase는 RLS를 통해 권한 관리를 세밀하게 설정 가능 (기본적으로 활성화 상태)
  • 베타 기능: 서버리스 함수(Function), Edge 기능 등은 아직 베타 상태이므로 주의

8. 결론

Supabase는 Firebase와 유사한 방식으로 빠르고 간편하게 백엔드를 구축할 수 있는 오픈 소스 솔루션입니다.
PostgreSQL을 기본 데이터베이스로 사용하기 때문에 개발자가 SQL에 익숙하다면 큰 이점을 누릴 수 있으며,
자동으로 생성되는 RESTful API와 인증, 스토리지까지 종합적으로 지원하여, 빠른 프로토타이핑 및 실제 서비스 운영에 유리합니다.

  • 장점: 오픈 소스, PostgreSQL 기반, 풍부한 기능
  • 단점: 일부 기능이 베타(서버리스 함수 등), 고급 기능 사용 시 학습 곡선 존재
  • 활용 예시: 토이 프로젝트, MVP, 스타트업 서비스 등

이상으로 간단히 Supabase를 프로젝트에 연동해 사용하는 방법에 대해 알아보았습니다.
더 궁금한 점이 있다면 공식 문서나 커뮤니티를 참고해보세요.