Supabase와 Vercel을 활용한 웹 서비스 개발
1. 서론
BaaS(Backend as a Service) 이해하기
BaaS(Backend as a Service)는 클라우드 컴퓨팅의 한 형태로, 웹과 모바일 애플리케이션 개발자가 클라우드 기반의 백엔드 서비스를 활용할 수 있게 해주는 서비스 모델입니다. BaaS는 API와 SDK를 통해 서비스에 연결하며 인증, 보안, 분석, 알림, 파일 저장, 데이터베이스 등의 기능을 제공합니다. 이러한 기능들은 미리 구축되어 있어 개발자는 프론트엔드 개발에 집중할 수 있습니다. AWS Amplify, Firebase, Netlify 등이 대표적인 BaaS 제공자이며, 오픈소스 BaaS로는 Appwrite, Parse, Supabase 등이 있습니다.
Supabase와 Vercel에 대한 간략한 소개
Supabase는 오픈 소스 BaaS로서, Google Firebase의 대안으로 소개하고 있습니다. PostgreSQL 데이터베이스를 기반으로 하며, 인증, 스토리지, 웹 소켓, 서버리스 함수 등의 백엔드 기능을 제공합니다. Supabase는 클라우드에서 가입만하여 바로 사용하거나, 로컬 환경에서 자체 호스팅하여 사용할 수 있습니다.
Vercel은 프론트엔드 개발에 초점을 맞춘 클라우드 플랫폼입니다. 정적 웹사이트와 서버리스 함수를 제공하며, 글로벌 CDN과 자동 배포, 확장 기능을 통해 서버 관리의 복잡성을 줄여줍니다.
이 글에서는 Supabase와 Vercel을 활용하여 간단한 웹서비스를 개발함으로써, BaaS의 실질적인 활용법을 경험해보도록 하겠습니다.
2. Supabase 시작하기
Supabase 프로젝트 생성 및 설정
Supabase를 사용하기 위해 먼저 계정을 생성합니다. Supabase 웹사이트에서 Start Your Project
버튼을 클릭하고, GitHub 계정 연동이나 Email, Password를 입력하여 계정을 생성합니다.
계정 생성 후, 새로운 프로젝트를 만들어야 합니다. New Project
버튼을 클릭하고, 프로젝트 이름, 데이터베이스 비밀번호, 리전 선택 등 필요한 정보를 입력합니다. 이후 프로젝트 설정을 완료하면 Supabase Dashboard에 접근하여 확인할 수 있습니다.
생성된 프로젝트에서 데이터베이스 테이블을 생성하고, 사용자 인증 등을 설정하며, API 키를 관리할 수 있습니다. 이 API 키는 Supabase 프로젝트를 웹 애플리케이션과 연동하는 데 사용됩니다.
Supabase에서 제공하는 예제 사용하기
Supabase는 기능을 이해하는 데 도움이 되는 다양한 예제를 제공하고 있습니다. (Supabase GitHub 저장소에서 찾을 수 있습니다.)
예제를 사용하려면 먼저 GitHub에서 해당 코드를 클론해야 합니다. 그런 다음, 코드의 설정 파일에 Supabase 프로젝트의 API 키와 URL을 입력합니다. 이렇게 하면 예제 애플리케이션을 로컬에서 실행하거나 배포하여 Supabase 프로젝트와 연동할 수 있습니다.
이 과정을 통해 Supabase를 사용하여 백엔드를 구축하고, 이를 웹 애플리케이션과 연동할 수 있습니다.
3. Vercel 시작하기
Vercel 프로젝트 생성 및 설정
Vercel을 사용하기 위해 먼저 계정을 생성합니다. Vercel 웹사이트에 접속하여 Sign Up
버튼을 클릭하고, 필요한 정보를 입력 후 Git provider와 연결하여 계정을 생성합니다.
계정 생성 후, 새로운 프로젝트를 만들어야 합니다. Add New
버튼을 클릭한 후 Project
를 선택합니다. Import Git Repository
또는 Clone Template
을 선택하여 프로젝트를 생성합니다.
대시보드에서는 프로젝트의 배포 상태를 확인하고, 배포 설정을 관리할 수 있습니다.
Supabase와 Vercel 연동하기
Supabase와 Vercel을 연동하려면 Supabase 프로젝트의 API 키와 URL을 Vercel 프로젝트의 환경 변수로 설정해야 합니다. 이를 위해 Vercel 프로젝트 Settings
탭의 Environment Variables
메뉴에서 Supabase 프로젝트의 API 키와 URL을 입력하거나, Supabase 프로젝트 Settings
탭의 Integrations
메뉴에서 Install Vercel Integration
을 클릭하여 설정할 수 있습니다.
환경 변수 설정 후, 웹 애플리케이션 코드에서 이 환경 변수를 사용하여 Supabase 클라이언트를 초기화 합니다. 이렇게 하면 웹 애플리케이션은 Supabase 프로젝트와 통신할 수 있게 됩니다.
이제 실제로 웹 서비스를 배포해 보겠습니다.
4. Supabase의 예제 활용하기
이 글에서는 배포할 웹 서비스를 위해 Supabase에서 제공하는 ‘todo-list’ 예제를 사용하겠습니다.
‘todo-list’ 예제 웹 서비스의 주요 기능 설명
Supabase Authentication을 활용한 사용자 인증 기능과 Supabase Database를 활용한 todo-list의 등록/수정/삭제 기능을 수행하는 웹 서비스 입니다.
코드 설명
⸰ 사용자 인증
Supabase Authentication을 활용한 사용자 인증을 위해서 미리 빌드 된 컴포넌트 Auth UI와 Auth Helpers를 import 한 후 이용합니다.
pages/api/index.tsx
......
import { useSession, useSupabaseClient } from '@supabase/auth-helpers-react'
import { Auth, ThemeSupa } from '@supabase/auth-ui-react'
......
export default function Home() {
const session = useSession()
const supabase = useSupabaseClient()
......
{!session ? (
......
<Auth supabaseClient={supabase} appearance={{ theme: ThemeSupa }} theme="dark" />
......
) : (
......
<TodoList session={session} />
<button
className="btn-black w-full mt-12"
onClick={async () => {
const { error } = await supabase.auth.signOut()
if (error) console.log('Error logging out:', error.message)
}}
>
Logout
</button>
</div>
)}
}
⸰ 데이터 등록
components/TodoList.tsx
......
import { Session, useSupabaseClient } from '@supabase/auth-helpers-react'
......
export default function TodoList({ session }: { session: Session }) {
const supabase = useSupabaseClient<Database>()
......
const addTodo = async (taskText: string) => {
let task = taskText.trim()
if (task.length) {
const { data: todo, error } = await supabase
.from('todos')
.insert({ task, user_id: user.id })
.select()
.single()
if (error) {
setErrorText(error.message)
} else {
setTodos([...todos, todo])
setNewTaskText('')
}
}
}
......
⸰ 데이터 수정
components/TodoList.tsx
......
import { Session, useSupabaseClient } from '@supabase/auth-helpers-react'
......
export default function TodoList({ session }: { session: Session }) {
const supabase = useSupabaseClient<Database>()
......
const toggle = async () => {
try {
const { data } = await supabase
.from('todos')
.update({ is_complete: !isCompleted })
.eq('id', todo.id)
.throwOnError()
.select()
.single()
if (data) setIsCompleted(data.is_complete)
} catch (error) {
console.log('error', error)
}
}
......
⸰ 데이터 삭제
components/TodoList.tsx
......
import { Session, useSupabaseClient } from '@supabase/auth-helpers-react'
......
export default function TodoList({ session }: { session: Session }) {
const supabase = useSupabaseClient<Database>()
......
const deleteTodo = async (id: number) => {
try {
await supabase.from('todos').delete().eq('id', id).throwOnError()
setTodos(todos.filter((x) => x.id != id))
} catch (error) {
console.log('error', error)
}
}
......
5. 배포 및 테스트
Vercel을 이용한 배포 과정
⸰ Import Git Repository
Supabase에서 제공하는 todo-list 예제의 Git Repository를 입력합니다.
작업할 GitHub 계정의 Repository Name을 입력합니다.
Error: supabaseUrl is required.
Supabase를 이용하기 위한 환경변수가 없으므로 초기 Build 에서는 에러가 발생하지만, Supabase와 Vercel를 연동하기를 통해 환경변수를 설정하여 해결합니다.
⸰ 테이블 생성
create table todos
create table todos (
id bigint generated by default as identity primary key,
user_id uuid references auth.users not null,
task text check (char_length(task) > 3),
is_complete boolean default false,
inserted_at timestamp with time zone default timezone('utc'::text, now()) not null
);
alter table todos enable row level security;
create policy "Individuals can create todos." on todos for
insert with check (auth.uid() = user_id);
create policy "Individuals can view their own todos. " on todos for
select using (auth.uid() = user_id);
create policy "Individuals can update their own todos." on todos for
update using (auth.uid() = user_id);
create policy "Individuals can delete their own todos." on todos for
delete using (auth.uid() = user_id);
todos 테이블을 생성한 후 Row Level Security (RLS)를 활성화합니다.
Supabase Authentication을 활용해 로그인한 사용자가 생성한 Row만 insert, select, update, delete 하도록 policy를 생성합니다.
Supabase 프로젝트 SQL Editor에서 테이블 생성을 위한 SQL문을 입력 후 실행합니다.
⸰ Supabase와 Vercel 연동하기
Supabase 프로젝트 Settings
탭의 Integrations
메뉴에서 Install Vercel Integration
을 클릭합니다.
Vercel의 Integration 화면으로 전환되며, 연결할 Vercel 계정과 프로젝트 선택, 필요한 권한을 체크 후 Install
을 클릭합니다.
다시 Supabase의 Integration 화면으로 전환되며, 연결할 Supabase 프로젝트와 Vercel 프로젝트를 선택 후 Connect project
버튼을 클릭합니다.
Vercel 프로젝트 Settings
탭의 Environment Variables
메뉴에서 Supabase 프로젝트 연결을 위한 API 키와 URL 등의 환경변수를 확인할 수 있습니다.
만약 비밀번호 변경 등으로 인한 환경변수 재동기화가 필요한 경우에는 Supabase 프로젝트 Settings
탭의 Integrations
메뉴에서 연결된 프로젝트의 Manage
버튼을 클릭 후 Resync environment variables
를 선택합니다.
웹 서비스 테스트
⸰ 빌드, 배포
Vercel은 모든 브랜치의 push
에 대해 프리뷰 배포를 생성하며 변경사항에 대해서 프로덕션 배포 전에 미리 확인할 수 있습니다. 프로덕션 브랜치의 merge
나 push
에 대해 또는 vercel --prod
명령을 사용하면 프로덕션 배포를 생성합니다.
Vercel에서 새 프로젝트를 만들 때, 프로덕션 브랜치는 main
브랜치, master
브랜치, "프로덕션 브랜치" 설정(Bitbucket의 경우), 그리고 Git 리포지토리의 기본 브랜치 순서로 선택됩니다. Vercel 프로젝트 Settings
탭의 Git
메뉴에서 변경할 수 있습니다.
⸰ 웹 서비스: Sign Up
신규 사용자의 Email address와 Password를 입력한 후 Sign Up
버튼을 클릭합니다.
Supabase Authentication > Users에서 등록된 사용자를 확인합니다.
⸰ 웹 서비스: 데이터 입력
등록된 사용자로 로그인하면 Todo List 페이지로 이동합니다. 데이터를 입력하고 Add
버튼을 클릭합니다.
Supabase Database > Table Editor > todos 테이블을 선택하여 입력한 데이터를 확인합니다.
⸰ 웹 서비스: 데이터 수정
등록된 사용자로 로그인하면 Todo List 페이지로 이동합니다. 수정할 데이터 우측의 체크박스를 체크합니다.
Supabase Database > Table Editor > todos 테이블을 선택하여 변경한 데이터를 확인합니다.
⸰ 웹 서비스: 데이터 삭제
등록된 사용자로 로그인하면 Todo List 페이지로 이동합니다. 삭제할 데이터 우측의 X
아이콘을 클릭합니다.
Supabase Database > Table Editor > todos 테이블을 선택하여 삭제한 데이터를 확인합니다.
6. 결론
BaaS에 대한 이해를 높이기 위해서 Supabase와 Vercel을 활용하여 웹 서비스를 배포하는 과정을 경험해보았습니다. 이 두 플랫폼은 백엔드와 프론트엔드 개발에 필요한 복잡한 작업들을 단순화시켜주어, 개발자가 핵심 기능 개발에 집중할 수 있게 해줍니다.
BaaS의 장점 및 한계
BaaS의 장점은 개발 속도를 향상하고, 서버 관리에 대한 부담을 줄여주는 것입니다. 또한, BaaS는 미리 만들어진 백엔드 기능을 제공하므로, 개발자는 프론트엔드 개발에만 집중할 수 있습니다.
그러나, BaaS의 한계는 가격과 벤더 종속성입니다. 트래픽이 많아질수록 비용이 증가하며, 특정 벤더에 의존하게 되는 벤더 종속성 문제가 있습니다. 또한, BaaS가 제공하는 기능 외에 추가적인 기능을 구현하려면 제한적일 수 있습니다.
따라서, 이러한 장점과 한계를 고려하여 충분한 테스트와 함께 적용한다면 BaaS의 이점을 최대한 활용하면서도 잠재적인 위험을 줄일 수 있습니다.