Intégration Supabase avec Claude Code
Découvrez intégration Supabase avec Claude Code. Conseils pratiques et exemples de code inclus.
Supabase とは
Supabaseはオープンソースのバックエンドプラットフォームです。PostgreSQLデータベース、認証、リアルタイムサブスクリプション、ストレージを統合的に提供します。Claude Codeを使えば、Supabaseの各機能を効率的に実装できます。
セットアップ
// lib/supabase.ts
import { createClient } from "@supabase/supabase-js";
import type { Database } from "./database.types";
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
export const supabase = createClient<Database>(
supabaseUrl,
supabaseAnonKey
);
// サーバーサイド用(Service Role Key)
export function createServerClient() {
return createClient<Database>(
supabaseUrl,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
{ auth: { persistSession: false } }
);
}
認証
// メール/パスワード認証
async function signUp(email: string, password: string) {
const { data, error } = await supabase.auth.signUp({
email,
password,
options: {
data: { display_name: email.split("@")[0] },
},
});
if (error) throw error;
return data;
}
async function signIn(email: string, password: string) {
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) throw error;
return data;
}
// OAuth認証
async function signInWithGitHub() {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: "github",
options: {
redirectTo: `${window.location.origin}/auth/callback`,
},
});
if (error) throw error;
return data;
}
// 認証状態の監視
supabase.auth.onAuthStateChange((event, session) => {
if (event === "SIGNED_IN") {
console.log("Signed in:", session?.user.email);
} else if (event === "SIGNED_OUT") {
console.log("Signed out");
}
});
データベースCRUD
// 型安全なクエリ
async function getPosts(params: {
page?: number;
category?: string;
}) {
const { page = 1, category } = params;
const perPage = 20;
let query = supabase
.from("posts")
.select(`
id,
title,
content,
published_at,
author:users(id, name, avatar),
categories(id, name, slug)
`, { count: "exact" })
.eq("published", true)
.order("published_at", { ascending: false })
.range((page - 1) * perPage, page * perPage - 1);
if (category) {
query = query.contains("categories", [{ slug: category }]);
}
const { data, error, count } = await query;
if (error) throw error;
return { posts: data, total: count };
}
// 挿入
async function createPost(post: {
title: string;
content: string;
}) {
const { data: { user } } = await supabase.auth.getUser();
if (!user) throw new Error("Not authenticated");
const { data, error } = await supabase
.from("posts")
.insert({
title: post.title,
content: post.content,
author_id: user.id,
})
.select()
.single();
if (error) throw error;
return data;
}
リアルタイムサブスクリプション
import { useEffect, useState } from "react";
function useRealtimeComments(postId: string) {
const [comments, setComments] = useState<Comment[]>([]);
useEffect(() => {
// 初期データ取得
supabase
.from("comments")
.select("*, author:users(name, avatar)")
.eq("post_id", postId)
.order("created_at")
.then(({ data }) => setComments(data || []));
// リアルタイム購読
const channel = supabase
.channel(`comments:${postId}`)
.on(
"postgres_changes",
{
event: "INSERT",
schema: "public",
table: "comments",
filter: `post_id=eq.${postId}`,
},
async (payload) => {
// 作者情報を取得
const { data } = await supabase
.from("users")
.select("name, avatar")
.eq("id", payload.new.author_id)
.single();
setComments((prev) => [
...prev,
{ ...payload.new, author: data },
]);
}
)
.subscribe();
return () => {
supabase.removeChannel(channel);
};
}, [postId]);
return comments;
}
ストレージ
async function uploadAvatar(file: File, userId: string) {
const ext = file.name.split(".").pop();
const path = `avatars/${userId}.${ext}`;
const { error: uploadError } = await supabase.storage
.from("profiles")
.upload(path, file, {
upsert: true,
contentType: file.type,
});
if (uploadError) throw uploadError;
const { data } = supabase.storage
.from("profiles")
.getPublicUrl(path);
// プロフィールを更新
await supabase
.from("users")
.update({ avatar: data.publicUrl })
.eq("id", userId);
return data.publicUrl;
}
Row Level Security
-- RLSポリシーの設定
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- 公開済み記事は誰でも閲覧可
CREATE POLICY "Public posts are viewable by everyone"
ON posts FOR SELECT
USING (published = true);
-- 自分の記事のみEdit可
CREATE POLICY "Users can update own posts"
ON posts FOR UPDATE
USING (auth.uid() = author_id);
-- 認証済みユーザーのみ作成可
CREATE POLICY "Authenticated users can create posts"
ON posts FOR INSERT
WITH CHECK (auth.uid() = author_id);
Claude Codeでの活用
Supabase開発をClaude Codeに依頼する例です。認証についてはOAuth認証の実装、データベース設計はPrisma ORM完全ガイドも参照してください。
Supabaseでブログアプリのバックエンドを構築して。
- 認証: メール/パスワード + GitHub OAuth
- テーブル: users, posts, comments, categories
- RLSポリシーの設定
- リアルタイムコメント機能
- 画像アップロード機能
Supabaseの詳細はSupabase公式ドキュメントを参照してください。Claude Codeの使い方は公式ドキュメントで確認できます。
Summary
Supabaseは認証からデータベース、リアルタイムまでを統合的に提供するプラットフォームです。Claude Codeを使えば、各機能の実装を効率的に進め、フルスタックアプリケーションを素早く構築できます。
PDF gratuit : aide-mémoire Claude Code en 5 minutes
Laissez simplement votre e-mail et nous vous enverrons immédiatement l'aide-mémoire A4 en PDF.
Nous traitons vos données avec soin et n'envoyons jamais de spam.
À propos de l'auteur
Masa
Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.
Articles similaires
7 vérifications avant de publier chaque jour un article multilingue sur Claude Code
Une checklist pratique pour publier des articles multilingues sur Claude Code chaque jour sans oublier une langue, casser les CTA ou laisser l’ancien contenu en production.
Codex Automations : confier l'analyse, les articles et le deploiement a l'IA
Guide pratique pour utiliser Codex Automations dans une operation de contenu orientee monetisation.
Claude Code × GCP Cloud Functions Guide Complet | Développement Serverless Ultra-Rapide
Optimisez GCP Cloud Functions avec Claude Code. Implémentez des triggers HTTP/Pub/Sub/Firestore, des tests locaux et l'automatisation des déploiements avec des exemples de code réels de l'expérience de Masa.