Supabase: Vibe Coder向けのバックエンド
概要
素晴らしいものを作りたいけれど、バックエンドの作業は完全に苦痛に感じる、そんなことありませんか?データベース、認証、サーバー……多すぎます。数回のクリックと少しのコードですべてを解決できたらどうでしょう?
そこで Supabase です。オープンソースのプラットフォームで、データベース、ユーザー認証、ファイルストレージなどを備えた完全なバックエンドを提供します。バックエンドの天才でなくても使えます。Vibe codingに最適です。重要なこと、つまりアプリを作り、アイデアを素早く形にすることに集中できます。
このチュートリアルでは、Supabaseの必須機能を解説します。セットアップ方法、データの保存と取得、ユーザー登録の処理、ファイルの保存までカバーします。
Vibeを感じましょう 🤗
ステップ1: Supabaseプロジェクトを始める
まず、Supabaseアカウントとプロジェクトが必要です。
- supabase.comにアクセスしてサインアップします。GitHubアカウントを使えば非常に速いです。
- ログインしたら、新しいOrganizationを作成し、"New Project"を作成します。
- プロジェクト名を付け、安全なデータベースパスワードを生成し(パスワードマネージャーなどに保存してください!)、自分に近いリージョンを選択します。
- バックエンドが構築されます!
準備ができたら、プロジェクトダッシュボード → Project Settingsに移動します。アプリに必要な重要な環境変数を取得します。
- Data APIセクションでProject URLを確認します。
- API KeysセクションでPublishable keyとSecret keyを確認します。
このタブは開いたままにしてください。まもなくアプリにこれらのキーをコピーします。
ステップ2: todosテーブルを作成する
Table Editorを使用するか、以下のSQLを実行します。
create table if not exists public.todos (
id bigint generated by default as identity primary key,
user_id uuid not null references auth.users (id) on delete cascade,
title text not null,
is_complete boolean not null default false,
inserted_at timestamp with time zone default now()
);
alter table public.todos enable row level security;
ステップ3: アプリでSupabaseを初期化する
クライアントをインストールします。
npm install @supabase/supabase-js
ブラウザ用のクライアントファイルを作成します(RLSとポリシーで安全です)。
// lib/supabaseClient.js import { createClient } from '@supabase/supabase-js' const supabaseUrl = 'YOUR_SUPABASE_PROJECT_URL' const supabaseKey = 'YOUR_SUPABASE_PUBLISHABLE_KEY' // 旧称 "anon" key export const supabase = createClient(supabaseUrl, supabaseKey) // Tip: 環境変数を優先しましょう (Astro/Nextなど) // const supabaseUrl = import.meta.env.PUBLIC_SUPABASE_URL // const supabaseKey = import.meta.env.PUBLIC_SUPABASE_PUBLISHABLE_KEY
サーバーコード(APIルート、CRON、Webhook)もある場合は、そこだけSecret keyを使用します。
// server/supabaseServer.js (Node/Edge runtime) import { createClient } from '@supabase/supabase-js' export const supabaseServer = createClient( process.env.SUPABASE_URL, process.env.SUPABASE_SECRET_KEY // クライアントに決して公開しない )
ステップ4: 認証 — サインアップとサインイン
// Sign up async function signUpUser(email, password) { const { data, error } = await supabase.auth.signUp({ email, password }) if (error) { console.error('Error signing up:', error.message); return null } return data.user } // Sign in async function signInUser(email, password) { const { data, error } = await supabase.auth.signInWithPassword({ email, password }) if (error) { console.error('Error signing in:', error.message); return null } return data.user }
ステップ5: CRUD — Todoの追加、一覧、切り替え、削除
// Add a todo (requires authenticated user) async function addTodo(title) { const { data: { user } } = await supabase.auth.getUser() if (!user) throw new Error('Not signed in') const { data, error } = await supabase .from('todos') .insert([{ title, user_id: user.id }]) .select() if (error) { console.error('Error adding todo:', error.message); return null } return data } // List todos (most recent first) async function fetchTodos() { const { data, error } = await supabase .from('todos') .select('*') .order('inserted_at', { ascending: false }) if (error) { console.error('Error fetching todos:', error.message); return [] } return data } // Toggle completion async function toggleTodo(todoId, nextComplete) { const { data, error } = await supabase .from('todos') .update({ is_complete: nextComplete }) .eq('id', todoId) .select() if (error) { console.error('Error updating todo:', error.message); return null } return data } // Delete a todo async function deleteTodo(todoId) { const { error } = await supabase .from('todos') .delete() .eq('id', todoId) if (error) { console.error('Error deleting todo:', error.message) } }
ステップ6: RLSで保護する(ポリシー)
Publishable keyは、Row Level Security(RLS)が有効でポリシーが正しい場合にのみクライアントに安全です。テーブルを行の所有者にロックします。
create policy "Select own todos" on public.todos
for select using (auth.uid() = user_id);
create policy "Insert own todos" on public.todos
for insert with check (auth.uid() = user_id);
create policy "Update own todos" on public.todos
for update using (auth.uid() = user_id);
create policy "Delete own todos" on public.todos
for delete using (auth.uid() = user_id);
オプション: Realtime更新
const { data: { user } } = await supabase.auth.getUser() const channel = supabase .channel('todos-changes') .on('postgres_changes', { event: '*', schema: 'public', table: 'todos', filter: `user_id=eq.${user.id}` }, payload => { console.log('Change received!', payload) // 例: 再取得またはローカルステートの更新 }) .subscribe()
まとめ
Supabaseを使って安全なTodoバックエンドを構築しました。
todosテーブルの作成- Publishable keyを使ったクライアントの接続
- 認証とCRUDの実装
- RLSポリシーによるデータ保護
- (オプション)Realtime更新
あとは、お好みのUIフレームワークに接続して出荷しましょう。Vibe on.