Supabase: Vibe Coder向けのバックエンド

Last updated: September 10 2025

概要

素晴らしいものを作りたいけれど、バックエンドの作業は完全に苦痛に感じる、そんなことありませんか?データベース、認証、サーバー……多すぎます。数回のクリックと少しのコードですべてを解決できたらどうでしょう?

そこで Supabase です。オープンソースのプラットフォームで、データベース、ユーザー認証、ファイルストレージなどを備えた完全なバックエンドを提供します。バックエンドの天才でなくても使えます。Vibe codingに最適です。重要なこと、つまりアプリを作り、アイデアを素早く形にすることに集中できます。

このチュートリアルでは、Supabaseの必須機能を解説します。セットアップ方法、データの保存と取得、ユーザー登録の処理、ファイルの保存までカバーします。

Vibeを感じましょう 🤗

ステップ1: Supabaseプロジェクトを始める

まず、Supabaseアカウントとプロジェクトが必要です。

  1. supabase.comにアクセスしてサインアップします。GitHubアカウントを使えば非常に速いです。
  2. ログインしたら、新しいOrganizationを作成し、"New Project"を作成します。
  3. プロジェクト名を付け、安全なデータベースパスワードを生成し(パスワードマネージャーなどに保存してください!)、自分に近いリージョンを選択します。
  4. バックエンドが構築されます!

準備ができたら、プロジェクトダッシュボード → Project Settingsに移動します。アプリに必要な重要な環境変数を取得します。

  • Data APIセクションでProject URLを確認します。
  • API KeysセクションでPublishable keyとSecret keyを確認します。

このタブは開いたままにしてください。まもなくアプリにこれらのキーをコピーします。

ステップ2: todosテーブルを作成する

Table Editorを使用するか、以下のSQLを実行します。

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を初期化する

クライアントをインストールします。

bash
npm install @supabase/supabase-js

ブラウザ用のクライアントファイルを作成します(RLSとポリシーで安全です)。

javascript
// 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を使用します。

javascript
// 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: 認証 — サインアップとサインイン

javascript
// 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の追加、一覧、切り替え、削除

javascript
// 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)が有効でポリシーが正しい場合にのみクライアントに安全です。テーブルを行の所有者にロックします。

sql
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更新

javascript
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.