Supabaseは、Firebaseの強力なオープンソース代替として急速に台頭しており、開発者にPostgreSQLデータベースを中心に構築されたツールのスイートを提供しています。Supabaseの中心には、データベースの上にインスタントでリアルタイムのAPIレイヤーがあり、バックエンド開発を大幅に加速します。このガイドでは、Supabase APIを活用する方法の包括的な概要を提供し、初期設定や基本操作からセキュリティ、カスタマイズ、型安全性までを網羅します。
開発チームが最大の生産性で一緒に作業できる統合型のオールインワンプラットフォームが欲しいですか?
Apidogはあなたのニーズに応え、Postmanをより手頃な価格で置き換えます!

ボタン
1. はじめに: Supabase APIとは?
従来のバックエンド開発では、データベースと対話するためにRESTまたはGraphQLエンドポイントを構築するのにかなりの時間を費やすことがある一方で、Supabaseは自動的に安全で高性能なAPIを生成します。Supabase PostgreSQLデータベースにテーブルを作成すると、SupabaseはオープンソースツールであるPostgRESTを使用してデータベーススキーマを調査し、対応するRESTfulエンドポイントを提供します。
主な利点:
- インスタントバックエンド: データベーススキーマを定義するとすぐに機能するAPIエンドポイントが得られます。
- リアルタイム機能: WebSocketsを介してデータベースの変更を購読します。
- PostgreSQLに基づく: 行レベルセキュリティ(RLS)などの機能を含むPostgreSQLの力、柔軟性、成熟度を活用します。
- 複数の相互作用方法: REST、GraphQL(コミュニティサポート)、またはSupabaseのクライアントライブラリ(JavaScript、Python、Dartなど)を介して対話します。
- 拡張性: 複雑なロジックや統合のためにカスタムサーバーレス関数(エッジ関数)を作成します。
このガイドは主にREST APIとそのクライアントライブラリを介した相互作用、およびSupabaseエッジ関数に焦点を当てています。
2. Supabase APIの始め方
Supabase APIを理解する最も簡単な方法は、すぐに始めることです。Supabaseプロジェクトが設定されていると仮定しましょう(まだの場合は、supabase.comにアクセスして無料で作成してください)そして、例えばprofiles
というシンプルなテーブルを作成します。
-- 公開プロファイル用のテーブルを作成
create table profiles (
id uuid references auth.users not null primary key,
updated_at timestamp with time zone,
username text unique,
avatar_url text,
website text,
constraint username_length check (char_length(username) >= 3)
);
-- 行レベルセキュリティ(RLS)を設定
-- 詳細はhttps://supabase.com/docs/guides/auth/row-level-securityを参照してください。
alter table profiles
enable row level security;
create policy "公開プロファイルは誰でも閲覧可能。" on profiles
for select using (true);
create policy "ユーザーは自分のプロファイルを挿入できます。" on profiles
for insert with check (auth.uid() = id);
create policy "ユーザーは自分のプロファイルを更新できます。" on profiles
for update using (auth.uid() = id);
-- このトリガーは、新しいユーザーがSupabase Authを通じてサインアップする際にプロファイルのエントリを自動的に作成します。
-- 詳細はhttps://supabase.com/docs/guides/auth/managing-user-data#using-triggersを参照してください。
create function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, username)
values (new.id, new.raw_user_meta_data->>'username');
return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
(注:上記の例では、profiles
を使用しており、これはSupabaseの標準例に合致しています。この概念は、todos
テーブルや作成する他のテーブルにも同様に適用されます。)
API資格情報の見つけ方:
すべてのSupabaseプロジェクトには固有のAPI資格情報があります:
- プロジェクトURL: あなたの固有のSupabaseエンドポイント(例:
https://<your-project-ref>.supabase.co
)。 - APIキー: Supabaseプロジェクトダッシュボードの
プロジェクト設定
>API
にあります。
anon
(公開)キー:このキーはクライアント側のアプリケーション(ブラウザやモバイルアプリなど)で使用するのが安全です。行レベルセキュリティ(RLS)を頼りにデータへのアクセスを制御します。service_role
キー:これは完全な管理権限を持つ秘密のキーであり、RLSをバイパスします。このキーをクライアント側のコードで公開しないでください。 セキュアなサーバー環境(バックエンドサーバーやサーバーレス関数など)でのみ使用してください。
APIとの相互作用(Supabase JSクライアントライブラリを使用):
SupabaseはAPIの相互作用を簡素化するためのクライアントライブラリを提供しています。以下はJavaScriptライブラリ(supabase-js
)を使用する方法です:
// 1. クライアントをインポートして初期化
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'https://<your-project-ref>.supabase.co'
const supabaseAnonKey = '<your-anon-key>'
const supabase = createClient(supabaseUrl, supabaseAnonKey)
// 2. データを取得(SELECT *)
async function getProfiles() {
const { data, error } = await supabase
.from('profiles')
.select('*')
if (error) console.error('プロファイルの取得中にエラーが発生しました:', error)
else console.log('プロファイル:', data)
}
// 3. データを挿入(INSERT)
async function createProfile(userId, username) {
const { data, error } = await supabase
.from('profiles')
.insert([
{ id: userId, username: username, updated_at: new Date() },
])
.select() // 挿入されたデータを返します
if (error) console.error('プロファイルの作成中にエラーが発生しました:', error)
else console.log('作成されたプロファイル:', data)
}
// 4. データを更新(UPDATE)
async function updateProfileUsername(userId, newUsername) {
const { data, error } = await supabase
.from('profiles')
.update({ username: newUsername, updated_at: new Date() })
.eq('id', userId) // idが一致する場合のみ更新
.select()
if (error) console.error('プロファイルの更新中にエラーが発生しました:', error)
else console.log('更新されたプロファイル:', data)
}
// 5. データを削除(DELETE)
async function deleteProfile(userId) {
const { data, error } = await supabase
.from('profiles')
.delete()
.eq('id', userId) // idが一致する場合のみ削除
if (error) console.error('プロファイルの削除中にエラーが発生しました:', error)
// 注:削除は成功時に最小限のデータを返すことが多く、特に一部のバージョン/セットアップでは.delete()の前に.select()を使用しない限り。
else console.log('プロファイルが正常に削除されました')
}
// 使用例(ユーザーIDがあると仮定)
// getProfiles();
// createProfile('some-uuid-v4', 'new_user');
// updateProfileUsername('some-uuid-v4', 'updated_username');
// deleteProfile('some-uuid-v4');
このクイックスタートは、クライアントライブラリを使用した基本的なCRUD(作成、読み取り、更新、削除)操作を示しており、内部的にREST APIを呼び出します。
3. 自動生成されたSupabase REST API
クライアントライブラリは便利ですが、PostgRESTによって生成された基盤となるREST APIの理解は重要です。
APIエンドポイントの構造:
REST APIの基本URLは通常次のとおりです:https://<your-project-ref>.supabase.co/rest/v1/
テーブル用に自動的に生成されたエンドポイント:
GET /rest/v1/your_table_name
: テーブルから行を取得します。POST /rest/v1/your_table_name
: テーブルに新しい行を挿入します。PATCH /rest/v1/your_table_name
: テーブル内の既存の行を更新します。DELETE /rest/v1/your_table_name
: テーブルから行を削除します。
認証:
APIリクエストには、apikey
ヘッダーにAPIキーを含める必要があります。また、通常はAuthorization
ヘッダーにBearer <your-api-key>
を含めます(クライアント側のリクエストには通常同じanon
キーが使用され、サーバー側にはservice_role
キーが使用されます)。
apikey: <your-anon-or-service-role-key>
Authorization: Bearer <your-anon-or-service-role-key>
一般的な操作(curl
の例を使用):
前述の例を用いて、REST APIに対して直接curl
を使用して再現してみましょう。適宜プレースホルダーを置き換えてください。
データを取得(GET):
curl 'https://<ref>.supabase.co/rest/v1/profiles?select=*' \
-H "apikey: <anon-key>" \
-H "Authorization: Bearer <anon-key>"
データを挿入(POST):
curl 'https://<ref>.supabase.co/rest/v1/profiles' \
-X POST \
-H "apikey: <anon-key>" \
-H "Authorization: Bearer <anon-key>" \
-H "Content-Type: application/json" \
-H "Prefer: return=representation" \# オプション:挿入された行を返します \
-d '{ "id": "some-uuid", "username": "rest_user" }'
データを更新(PATCH):(ユーザー名が'rest_user'のプロファイルを更新)
curl 'https://<ref>.supabase.co/rest/v1/profiles?username=eq.rest_user' \
-X PATCH \
-H "apikey: <anon-key>" \
-H "Authorization: Bearer <anon-key>" \
-H "Content-Type: application/json" \
-H "Prefer: return=representation" \
-d '{ "website": "https://example.com" }'
データを削除(DELETE):(ユーザー名が'rest_user'のプロファイルを削除)
curl 'https://<ref>.supabase.co/rest/v1/profiles?username=eq.rest_user' \
-X DELETE \
-H "apikey: <anon-key>" \
-H "Authorization: Bearer <anon-key>"
フィルタリング、選択、順序、ページネーション:
REST APIは、URLパラメーターを使用した強力なクエリングをサポートしています:
- カラムの選択:
?select=column1,column2
- フィルタリング(等しい):
?column_name=eq.value
(例:?id=eq.some-uuid
) - フィルタリング(その他の演算子):
gt
(より大きい)、lt
(より小さい)、gte
、lte
、neq
(等しくない)、like
、ilike
(大文字小文字を区別しないlike)、in
(例:?status=in.(active,pending)
) - 順序付け:
?order=column_name.asc
または?order=column_name.desc
(必要に応じて.nullsfirst
または.nullslast
を追加) - ページネーション:
?limit=10&offset=0
(最初の10を取得)、?limit=10&offset=10
(次の10を取得)
自動生成されたAPIドキュメント:
Supabaseの最も役立つ機能の1つは、プロジェクトダッシュボード内で直接利用できる自動生成されたAPIドキュメントです。
- Supabaseプロジェクトに移動します。
- 左側のサイドバーにあるAPI Docsアイコンをクリックします(通常は
<>
のように見えます)。 - "テーブルとビュー"の下でテーブルを選択します。
- そのテーブルに特有のRESTエンドポイントの詳細なドキュメントが表示され、以下が含まれます:
- リクエストの例(Bash/
curl
, JavaScript)。 - 利用可能なフィルター、セレクター、修飾子。
- カラムやデータ型の説明。
このインタラクティブなドキュメントは、API呼び出しの構造を理解するのに非常に役立ちます。
4. Supabase APIを利用した高度な開発のための型生成
TypeScriptや他の型付き言語を使用するプロジェクトでは、Supabaseはデータベーススキーマから直接型定義を生成する方法を提供します。これにより、以下のような大きな利点があります:
- 型安全: 実行時ではなくコンパイル時にエラーを検出します。
- 自動補完: テーブル名、カラム名、関数パラメーターに対して、コードエディタ内でインテリジェントな提案を受けられます。
- メンテナンス性の向上: 型はデータ構造の生きたドキュメントとして機能します。
Supabase CLIを使用した型の生成:
- Supabase CLIをインストール:
https://supabase.com/docs/guides/cli
の指示に従ってください。 - ログイン:
supabase login
- プロジェクトとリンク:
supabase link --project-ref <your-project-ref>
(ローカルプロジェクトディレクトリ内で実行します)。データベースパスワードを提供する必要がある場合があります。 - 型を生成:
supabase gen types typescript --linked > src/database.types.ts
# またはリンクされていない、または異なるコンテキストの場合はプロジェクトIDを指定
# supabase gen types typescript --project-id <your-project-ref> > src/database.types.ts
このコマンドは、リンクされたSupabaseプロジェクトのデータベーススキーマを調査し、テーブル、ビュー、および関数の引数/戻り値の型を含むTypeScriptファイル(この例ではdatabase.types.ts
)を出力します。
生成された型の使用:
これらの型をアプリケーションコードにインポートできます:
import { createClient } from '@supabase/supabase-js'
// 生成された型をインポート
import { Database } from './database.types' // パスは必要に応じて調整
const supabaseUrl = 'https://<your-project-ref>.supabase.co'
const supabaseAnonKey = '<your-anon-key>'
// createClientにDatabase型を提供
const supabase = createClient<Database>(supabaseUrl, supabaseAnonKey)
// これで型安全性と自動補完が得られます!
async function getSpecificUserProfile(username: string) {
// テーブル名('profiles')の自動補完
const { data, error } = await supabase
.from('profiles')
// カラム名('id', 'username', 'website')の自動補完
.select('id, username, website')
// カラム型に対して値が型チェックされる
.eq('username', username)
.single() // 単一の結果またはnullを期待
if (error) {
console.error('プロファイルの取得中にエラーが発生しました:', error)
return null;
}
// 'data'は、選択クエリに基づいて正しく型付けされます
if (data) {
console.log(`ユーザーID: ${data.id}, ウェブサイト: ${data.website}`);
// console.log(data.non_existent_column); // <-- TypeScriptエラー!
}
return data;
}
型生成は、Supabaseを使用した強固なアプリケーション開発のための非常に推奨されるプラクティスです。
5. エッジ関数を使用したカスタムSupabase APIルートの作成
自動生成されたREST APIは標準的なCRUD操作をカバーしますが、次のようなカスタムサーバーサイドロジックが必要になることがよくあります:
- サードパーティサービスとの統合(例:Stripe、Twilio)。
- 複雑な計算やデータ集約の実行。
- クライアントにキーを公開せずに特権アクセス(
service_role
キー)を必要とするロジックの実行。 - 複雑なビジネスルールの強制。
Supabaseのエッジ関数は、ユーザーに近いエッジでDenoベースのTypeScript関数をグローバルにデプロイする方法を提供します。
エッジ関数の作成:
- 関数を初期化(まだ行っていない場合):
supabase functions new hello-world
(リンクされたプロジェクトディレクトリ内で実行します)。これにより、supabase/functions/hello-world/index.ts
ファイルが作成されます。
関数コードを書く:
// supabase/functions/hello-world/index.ts
import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' // 適切なstdバージョンを使用
serve(async (req) => {
// 'req'からリクエストヘッダー、メソッド、ボディなどにアクセスできます
console.log(`リクエストが受信されました: ${req.url}`);
// 例:関数内からSupabase DBにアクセス
// 注:関数内でSupabaseクライアントを設定する必要があります
// 環境変数を使用して秘密を管理してください!
// import { createClient } from '@supabase/supabase-js'
// const supabaseAdmin = createClient(
// Deno.env.get('SUPABASE_URL') ?? '',
// Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
// )
// const { data: users, error } = await supabaseAdmin.from('profiles').select('*').limit(10);
const data = {
message: `エッジからこんにちは!`,
// users: users // データを取得する場合の例
}
return new Response(
JSON.stringify(data),
{ headers: { 'Content-Type': 'application/json' } },
)
})
関数をデプロイ:
supabase functions deploy hello-world --no-verify-jwt
# 公開アクセス可能な関数のために--no-verify-jwtを使用
# 省略するか、--verify-jwt=trueを設定して有効なSupabase Auth JWTを要求
関数を呼び出す:
デプロイされた関数にはHTTP POSTリクエスト(または関数ロジックに応じてGET)を介してそのユニークなエンドポイントに呼び出すことができます:https://<your-project-ref>.supabase.co/functions/v1/hello-world
curl
を使用:
curl -X POST 'https://<ref>.supabase.co/functions/v1/hello-world' \
-H "Authorization: Bearer <user-jwt-if-required>" \
-H "Content-Type: application/json" \
-d '{"name": "Functions"}' # オプションのリクエストボディ
またはSupabase JSクライアントを使用:
const { data, error } = await supabase.functions.invoke('hello-world', {
method: 'POST', // 'GET'など、任意
body: { name: 'Functions' }
})
エッジ関数は、単純なデータベース操作を超えてSupabaseバックエンド機能を拡張するための強力なツールです。
6. APIキーとSupabase APIのセキュリティ
APIキーを理解し、適切なセキュリティ対策を実施することは、譲れないものです。
APIキーの要約:
anon
(公開)キー:クライアント側の使用のため。データ保護のために完全に行レベルセキュリティ(RLS)に依存しています。service_role
キー:サーバー側専用の使用のため。RLSをバイパスし、完全なデータベースアクセスを許可します。このキーを慎重に保護してください。
行レベルセキュリティ(RLS)の重要な役割:
RLSは、anon
キーを使用する際のSupabaseセキュリティの礎です。これは、PostgreSQLデータベース内で直接きめ細かなアクセス制御ポリシーを定義することを可能にします。ポリシーは、ユーザーがビュー、挿入、更新、または削除できる行を決定するSQLルールです。これには、認証されたステータス、ユーザーID、役割、または他の基準が含まれます。
RLSの有効化:
デフォルトでは、新しいテーブルのRLSは無効です。anon
キーを使用してクライアント側からアクセスする予定のテーブルに対しては、有効にする必要があります。
-- 'profiles'テーブルでRLSを有効化
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
-- 重要:RLSを有効にした後にポリシーが定義されていない場合、
-- すべての操作(テーブルの所有者を除く)についてアクセスが暗黙的に拒否されます。
RLSポリシーの作成:
ポリシーは、USING
句(SELECT
、UPDATE
、DELETE
などの読み取りアクセス用)と、WITH CHECK
句(INSERT
、UPDATE
などの書き込みアクセス用)を定義します。
例1: 認証済みユーザーがすべてのプロファイルを読み取れるようにする:
CREATE POLICY "認証済み読み取りアクセスの許可"
ON profiles FOR SELECT
USING ( auth.role() = 'authenticated' );
例2: ユーザーが自分のプロファイルのみを表示できるようにする:
CREATE POLICY "個別読み取りアクセスの許可"
ON profiles FOR SELECT
USING ( auth.uid() = id ); -- 'id'カラムがSupabase AuthからのユーザーのUUIDに一致することを想定
例3: ユーザーが自分のプロファイルのみを更新できるようにする:
CREATE POLICY "個別更新アクセスの許可"
ON profiles FOR UPDATE
USING ( auth.uid() = id ) -- 更新対象となる行を指定
WITH CHECK ( auth.uid() = id ); -- 新しいデータが条件に一致することを保証
例4: ユーザーが自分のプロファイルを挿入できるようにする:
CREATE POLICY "個別挿入アクセスの許可"
ON profiles FOR INSERT
WITH CHECK ( auth.uid() = id );
RLSポリシーは、SupabaseダッシュボードのAuthentication
> Policies
の下で直接表示、作成、管理できます。
主要なセキュリティ原則:
- 常にRLSを有効にすること。
anon
キーを使用してアクセスされるテーブルに対して。 - 必要に応じて、
SELECT
、INSERT
、UPDATE
、DELETE
のための明示的なポリシーを定義する。制限的なポリシーから始めて、アクセスを慎重に緩和する。 service_role
キーを決してクライアント側のコードや不secureな環境で公開しないでください。- 特権の必要な操作や複雑なサーバーサイドロジックには、エッジ関数を使用し、関数のセキュアな環境変数内で
service_role
キーを保護します。 - 定期的にRLSポリシーを見直すこと。アプリケーションのセキュリティ要件を満たしているか確認します。
7. SQL概念をSupabase API(SQLからAPI)にマッピングする
SQLに精通しているなら、一般的なSQL操作がSupabase API(RESTとクライアントライブラリの両方)にどのようにマッピングされるかを理解することは便利です。
SELECT * FROM my_table;
- REST:
GET /rest/v1/my_table?select=*
- JS:
supabase.from('my_table').select('*')
SELECT column1, column2 FROM my_table WHERE id = 1;
- REST:
GET /rest/v1/my_table?select=column1,column2&id=eq.1
- JS:
supabase.from('my_table').select('column1, column2').eq('id', 1)
INSERT INTO my_table (column1, column2) VALUES ('value1', 'value2');
- REST:
POST /rest/v1/my_table
でJSONボディ{"column1": "value1", "column2": "value2"}
- JS:
supabase.from('my_table').insert({ column1: 'value1', column2: 'value2' })
UPDATE my_table SET column1 = 'new_value' WHERE id = 1;
- REST:
PATCH /rest/v1/my_table?id=eq.1
でJSONボディ{"column1": "new_value"}
- JS:
supabase.from('my_table').update({ column1: 'new_value' }).eq('id', 1)
DELETE FROM my_table WHERE id = 1;
- REST:
DELETE /rest/v1/my_table?id=eq.1
- JS:
supabase.from('my_table').delete().eq('id', 1)
ジョイン:基本的なREST呼び出しでは直接SQLのJOIN
構文は使用されませんが、次の方法で関連データを取得できます:
- 外部キーリレーションシップ:
?select=*,related_table(*)
で外部キーによって定義された関連テーブルからデータを取得します。 - JS:
supabase.from('my_table').select('*, related_table(*)')
- RPC(リモートプロシージャコール): 複雑なジョインやロジックについては、PostgreSQL関数を作成し、APIを介して呼び出します。
-- SQL関数の例
CREATE FUNCTION get_user_posts(user_id uuid)
RETURNS TABLE (post_id int, post_content text) AS $$
SELECT posts.id, posts.content
FROM posts
WHERE posts.author_id = user_id;
$$ LANGUAGE sql;
- REST:
POST /rest/v1/rpc/get_user_posts
でJSONボディ{"user_id": "some-uuid"}
- JS:
supabase.rpc('get_user_posts', { user_id: 'some-uuid' })
8. Supabase APIでのカスタムスキーマの使用
デフォルトでは、Supabase SQLエディタで作成したテーブルはpublic
スキーマ内に存在します。より良い整理、ネームスペース、または権限管理のために、カスタムPostgreSQLスキーマを使用することを検討するかもしれません。
カスタムスキーマの作成:
CREATE SCHEMA private_schema;
カスタムスキーマ内にテーブルを作成:
CREATE TABLE private_schema.sensitive_data (
id serial primary key,
payload jsonb
);
APIを介したカスタムスキーマ内のテーブルへのアクセス:
SupabaseのPostgRESTレイヤーは、public
以外のスキーマにあるテーブルを自動的に検出します。
- REST API: APIエンドポイントはそのまま(
/rest/v1/table_name
)ですが、PostgRESTはデフォルトで他のスキーマのテーブルを公開します。標準のRLSを超えてきめ細かなスキーマレベルのアクセス制御を希望する場合は、PostgreSQLのロールと権限を介してアクセスを管理する必要があることがあります。同じテーブル名の衝突(public
と他のスキーマに同じテーブル名がある場合)がある場合は、特定の設定が必要になることがあります。必要に応じてスキーマの可視性を処理するためにPostgRESTドキュメントを確認してください。 - クライアントライブラリ: クライアントライブラリはシームレスに機能します。テーブル名を通常通りに参照するだけです:
// 'private_schema'内のテーブルにアクセス(RLS/権限が許可されていることを前提)
const { data, error } = await supabase
.from('sensitive_data') // ここでスキーマ名をプレフィックスとして付ける必要はありません
.select('*')
.eq('id', 1);
Supabaseは内部でテーブル名を正しいスキーマにマッピングします。クロススキーマのクエリや関数を含む場合、RLSポリシーが正しくテーブルを参照することを確認してください。
カスタムスキーマの使用は、Supabaseが完全にサポートする標準のPostgreSQLプラクティスであり、より構造化されたデータベースの整理を可能にします。
9. 結論
Supabase APIは、PostgreSQLデータベースへのインスタントで安全、かつスケーラブルなアクセスを提供することにより、アプリケーションを構築するための非常に効率的な方法を提供します。自動生成されたRESTエンドポイントや便利なクライアントライブラリから、行レベルセキュリティによって提供される堅牢なセキュリティ、エッジ関数によって提供される拡張性まで、Supabaseは開発者がボイラープレートバックエンドインフラストラクチャではなく、機能の構築に集中できるようにしています。
APIキー、RLS、REST構造、型生成、カスタム関数というコア概念を理解することで、Supabaseプラットフォームのフルパワーを効果的に活用できます。セキュリティを最優先にしてください。
開発チームが最大の生産性で一緒に作業できる統合型のオールインワンプラットフォームが欲しいですか?
Apidogはあなたのニーズに応え、Postmanをより手頃な価格で置き換えます!

ボタン