처음 Supabase를 접하면 다음과 같은 코드를 작성하게 됩니다.
typescriptconst { data
Supabase와 PostgreSQL의 관계를 이해하고, SQL 직접 사용과 Prisma ORM 활용을 비교해 프로젝트에 맞는 데이터베이스 전략을 고르는 기준을 정리합니다.
2026. 3. 28.BackendPrisma에서 임베디드 엔티티 대신 1:1 관계와 JSONB 타입으로 복합 객체를 다루는 방법을 비교합니다.
2026. 3. 28.BackendSupabase의 anon key 노출 위험을 RLS(행 수준 보안) 정책으로 막는 원리와 실무 패턴을 정리합니다.
2026. 3. 28.이 코드는 Knex나 Prisma의 쿼리 빌더와 매우 유사해 보입니다. 그래서 많은 개발자가 "Supabase Client는 그냥 자바스크립트로 SQL을 짜게 해주는 도구"라고 생각하곤 합니다. 하지만 이 둘은 통신 프로토콜부터 보안 모델까지 모든 것이 다릅니다.
가장 큰 차이는 "누가 SQL을 만드는가"와 "데이터를 어떻게 전달하는가"에 있습니다.
전통적인 쿼리 빌더는 보통 Admin 권한으로 DB에 접근합니다. 즉, 서비스 로직에서 where user_id = current_user 같은 조건을 실수로 빼먹으면 전체 데이터가 유출되는 보안 사고로 이어질 수 있습니다.
반면 Supabase Client는 RLS(Row Level Security)를 기반으로 합니다.
이는 보안의 책임을 애플리케이션 코드에서 데이터베이스 엔진으로 옮긴 아키텍처적 전환입니다. 코드 기반 보안보다 더 강력하고 안전합니다.
Supabase Client가 제공하는 메서드 체이닝은 편리하지만, 복잡한 비즈니스 로직에서는 한계가 있습니다.
.from().update()를 호출하는 것은 각각 독립적인 HTTP 요청입니다. 네트워크 장애가 발생하면 데이터 정합성이 깨질 수 있습니다.typescript// 💡 복잡한 트랜잭션이나 로직은 RPC로 해결 const { data, error } = await supabase.rpc('process_order_and_inventory', { order_id: 123 });
동작 방식의 차이로 인해 장단점이 명확해집니다.
Supabase Client는 단순한 쿼리 빌더 그 이상입니다. 데이터베이스를 안전한 클라우드 API로 변모시켜 주는 도구에 가깝습니다.
체이닝의 편리함에만 집중하기보다는, RLS 정책 설계와 Stored Procedure(RPC)를 적절히 활용해 '프론트엔드-데이터베이스' 사이의 아키텍처를 얼마나 견고하게 설계하느냐를 함께 고민하는 것이 좋습니다.
오늘 작성한 .select().eq() 코드가 실제로는 어떤 HTTP 요청을 날리고 있는지 네트워크 탭에서 한번 확인해 보세요. 기술의 내부를 이해하면 더 나은 설계를 위한 눈이 열립니다.