3. Next.js (App Router)에서 데이터 관리 (CRUD)
Next.js 애플리케이션에서 Supabase 데이터베이스와 상호 작용하는 것은 간단합니다. 이 섹션에서는 Supabase 클라이언트를 사용하여 기본적인 CRUD (생성, 읽기, 업데이트, 삭제) 작업을 수행하는 방법을 보여줍니다.
3.1. 데이터베이스 테이블 설정
먼저 Supabase SQL 편집기에서 간단한 테이블을 생성합니다. 예를 들어, todos 테이블:
create table todos (
id uuid primary key default uuid_generate_v4(),
user_id uuid references auth.users not null,
task text,
is_complete boolean default false,
inserted_at timestamp with time zone default timezone('utc'::text, now()) not null
);
3.2. 데이터 읽기 (서버 컴포넌트)
서버 컴포넌트에서 데이터를 가져옵니다. 이 방법은 렌더링 전에 서버에서 데이터를 가져오므로 효율적입니다.
// app/todos/page.tsx
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'
export default async function TodosPage() {
const supabase = createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
redirect('/login')
}
const { data: todos, error } = await supabase
.from('todos')
.select('*')
.eq('user_id', user.id) // 인증된 사용자별 필터링
.order('inserted_at', { ascending: true })
if (error) {
console.error('할 일 가져오기 오류:', error.message)
return <div>할 일을 로드하는 중 오류가 발생했습니다.</div>
}
return (
<div>
<h1>내 할 일</h1>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
{todo.task} ({todo.is_complete ? '완료' : '진행 중'})
</li>
))}
</ul>
</div>
)
}
3.3. 데이터 생성 (클라이언트 컴포넌트/서버 액션)
새 데이터를 생성하려면 클라이언트 컴포넌트 또는 서버 액션을 사용할 수 있습니다. App Router에서 변경 작업을 위해서는 서버 액션이 권장됩니다.
// app/todos/create-todo.ts (서버 액션)
'use server'
import { createClient } from '@/lib/supabase/server'
import { revalidatePath } from 'next/cache'
export async function createTodo(formData: FormData) {
const supabase = createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
throw new Error('사용자가 인증되지 않았습니다')
}
const task = formData.get('task') as string
const { error } = await supabase
.from('todos')
.insert({ user_id: user.id, task })
if (error) {
console.error('할 일 생성 오류:', error.message)
throw error
}
revalidatePath('/todos') // 새 데이터를 표시하기 위해 할 일 페이지 재검증
}
// app/todos/page.tsx (클라이언트 컴포넌트 폼 내)
// ...
<form action={createTodo}>
<input type="text" name="task" placeholder="새로운 할 일" required />
<button type="submit">할 일 추가</button>
</form>
// ...
3.4. 데이터 업데이트 및 삭제 (클라이언트 컴포넌트/서버 액션)
생성과 마찬가지로 업데이트 및 삭제는 견고성과 보안을 위해 서버 액션으로 처리하는 것이 가장 좋습니다.
// 업데이트 예시 (서버 액션)
'use server'
import { createClient } from '@/lib/supabase/server'
import { revalidatePath } from 'next/cache'
export async function updateTodoStatus(todoId: string, isComplete: boolean) {
const supabase = createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
throw new Error('사용자가 인증되지 않았습니다')
}
const { error } = await supabase
.from('todos')
.update({ is_complete: isComplete })
.eq('id', todoId)
.eq('user_id', user.id) // 소유자만 업데이트할 수 있도록 보장
if (error) {
console.error('할 일 업데이트 오류:', error.message)
throw error
}
revalidatePath('/todos')
}
이 예시들은 Supabase를 사용하는 Next.js 애플리케이션에서 데이터를 관리하기 위한 견고한 기반을 제공합니다.