6개월간의 실사용 리뷰: Supabase의 장단점 분석

6개월 동안 Supabase를 직접 써보고 느낀 점들을 솔직하게 써보았습니다. supabase typegen을 활용한 type-safe한 개발부터 supabase Auth까지, Supabase의 장점과 단점을 과감하게 풀어보았습니다. 실제 사용 경험에서 얻은 꿀팁도 있으니, 이 글을 통해 supabase에 대해서 좀 더 자세히 알아갈 수 있는 시간이 되었으면 좋겠습니다.
Jan 19, 2024
6개월간의 실사용 리뷰: Supabase의 장단점 분석

Supabase란?

supabase는 firebase 대안으로 떠오르고 있는 Database SaaS 서비스입니다. 자세한 내용은 지난번 블로그에서 소개해드렸으니, 아래 링크를 통해서 확인하시면 좋을 것 같습니다

Supabase 핵심 장점 3가지

쉽게 type-safe한 개발이 가능합니다.

supabase에는 type-gen기능이 있습니다.
npx supabase gen types typescript --project-id "$PROJECT_REF" --schema public > types/supabase.ts
그래서 아래의 명령어를 입력하면 현재 데이터 베이스 구조에 맞는 type을 자동으로 생성해 줍니다.
notion image
이에 따라 실제로 supabase 함수를 호출하게 되면 자동으로 type이 추론되고, DB 스키마에 맞지 않는 요청을 하거나, 타입으로 인한 실수를 할 가능성이 현저하게 줄어듭니다.

손쉽게 인증 기능을 개발할 수 있습니다.

notion image
 
supabase는 인증 기능을 제공합니다. 이메일 로그인, Password 로그인, 소셜 로그인 등 다양한 로그인 방법들을 react 혹은 nextjs에서 정말 빠르고 편리하게 구현할 수 있습니다. 한국 플랫폼으로는 kakao가 지원되며, 아쉽게도 naver 로그인은 없습니다.
 
notion image
 
뿐만 아니라 인증과정에서 필요한 이메일들을 특별한 개발과정 없이 커스텀이 가능하고, Admin 환경에서 Email을 보내는게 가능하여, 운영에 드는 시간을 최소화할 수 있습니다.
 
notion image
 
또한 database에서 컬럼의 default 값으로 supabase Auth의 userID를 활용할 수 있어서 유저 로그인 후에는 userID 값을 매번 API 호출 때마다 기록할 필요가 없어집니다.
 

넉넉하게 무료로 사용할 수 있습니다.

notion image
 
supabase의 무료 tier는 강력합니다. 무료로 DB를 500MB까지 제공하며, supabase Auth의 경우, 월 5만명까지 무료로 제공하고 있습니다.
 
notion image
 
제가 실제 하고 있는 프로젝트 플러그 파인더의 경우, 충전소, 충전기 데이터를 총 포함하여 35만개의 row를 활요하고 있는데, DB 용량이 여전히 여유로운 것을 알 수 있습니다. 물론 아직 트래픽이 많지 않아서, 좀 더 지켜보아야 하지만 그럼에도 불구하고 충분히 매력적인 free-tier 정책인 것은 틀림이 없습니다.
 

Supabase의 너무나도 아쉬운 점 3가지

멀티 테이블 insert가 되지 않습니다.

아쉽게도 supabase library에서는 한 번에 여러 테이블에 insert가 불가능합니다. 그래서 보통 하는 방법은 아래와 같이 call을 두번 나눠서 합니다.
const title = 'New Book' const user_id = <user id> const { data } = await supabase .from('books) .insert({ title }) const book = data[0] // ignoring error handling for simplicity const { data, error } = await supabase .from('book_users) .insert({ user_id, book_id: book.id })
 
혹은 데이터가 많은 경우, rpc와 같은 postgres function을 만들어서 할 수 있습니다.
 
CREATE OR REPLACE FUNCTION public.insert_books( title text, user_id uuid ) RETURNS setof public.books AS $$ declare book_id uuid; begin INSERT into books (title) values (title) returning id into book_id; INSERT into book_users (book_id, user_id) values (book_id, user_id); RETURN query select * from boards where boards.id = board_id; END $$ language plpgsql;
 
위와 같이 rpc를 만든 후에, 아래와 같이 호출을 하면 사용이 가능합니다.
 
supabase.rpc('insert_books', { title: 'New book', user_id })
 

transaction 설정이 되지 않습니다.

notion image
2024.1.19 현재까지 transaction이 라이브러리를 통해서 공식적으로 지원되고 있지 않습니다. 트랜잭션을 반드시 사용해야 한다면, Drizzle ORM 혹은 Prisma와 같은 ORM 라이브러리를 통해서 사용해야 합니다.
 

RLS 설정을 반드시 해주어야 합니다.

Row-Level Security (RLS) in PostgreSQL은 데이터베이스의 각 행에 대한 접근 제어를 가능하게 하는 기능입니다. 이를 통해 사용자나 역할에 따라 데이터베이스 내 특정 행에 대한 접근을 제한하거나 허용할 수 있습니다. 예를 들어, 특정 사용자는 특정 데이터 행만 볼 수 있도록 설정할 수 있습니다. 이 기능은 민감한 데이터를 다룰 때 보안을 강화하는 데 유용합니다. RLS는 보안 정책을 정의하여 구현하며, 이 정책은 SQL 쿼리를 실행할 때 자동으로 적용됩니다. by chat GPT
 
supabase의 경우, 직접적으로 인증 로직을 컨트롤 할 수 있는 서버가 없고, DB에 query할 수 있는 키가 public으로 노출됩니다. 이러한 이유로 DB에서 특정 테이블에 접근 권한을 명확하게 해주어야 합니다.
 
notion image
 
위와 같이 내가 작성한 게임 기록에 한하여 보도록 하려면, authenticated와 같은 설정들을 통해 인증되지 않은 유저가 해당 데이터에 접근하는 것을 막아야 합니다.
또한 key가 노출되면, 해당 테이블 전체에 대해서 호출 할 수 있기 때문에, public 테이블이더라도 숨겨야 하는 데이터가 있다면 column level Security 설정을 하거나, 테이블을 분리하는게 필요합니다.
 
좀 더 자세한 내용이 궁금하다면, 아래 유튜브 영상을 보시는 것을 추천합니다
 

그럼에도 불구하고..

여러 단점이 있음에도 불구하고, 여전히 저는 supabase를 활용하고 있습니다.
  1. rpc 설정하는 것이 불편하긴 하지만, typesafe하면서 빠르게 개발할 수 있는 장점을 포기할 수 없었습니다.
  1. 한푼 한푼이 소중한 솔로프로너에게 무료 tier의 해자로움 또한 포기가 어려웠습니다.
  1. 마땅한 대안을 아직 찾지 못했습니다. supabase Auth와의 자연스러운 연결이 너무 편리해서 쉽게 떠나지 못하고 있습니다.
 
시간이 된다면 다음 프로젝트에서는 planetscale을 DB로 두고, Drizzle ORM 혹은 Prisma를 활용하여 DB를 구성하여 사용해본 후기를 남겨보도록 하겠습니다.

참고자료

하고 있는 프로젝트들

 
최근에 패스트 캠퍼스에서 NextJS 14, Supabase, Shadcn을 바탕으로 강의를 하게 되었습니다. 블로그에서 언급한 내용들을 대부분 다루고 있고, 제가 가진 모든 노하우를 집약해서 만들고 있습니다. 아래 링크를 통해서 등록하시면 20% 할인 가능하오니, 많은 관심 부탁드려요
Share article

More articles

See more posts

indietools