データベースとストレージのためにSupabaseをLaravelと統合する方法

最終更新: 5 12月2025
  • Supabase Postgres データベースを使用するように Laravel を構成するには、ドライバー、スキーマ、および環境変数を正しく調整する必要があります。
  • Supabase の Laravel 専用ドライバーは、クエリと結合における UUID 列の一般的な問題を自動的に解決します。
  • Flysystem アダプターを使用すると、Supabase ストレージを単なる別の Laravel ディスクとして扱い、ファイルのアップロードを簡単に統合できます。
  • 書き込みエラーを回避し、安定したフローを確保するには、特権サービス キーと適切に構成されたバケットを使用することが重要です。

Laravel 用の Supabase

Laravelを使ってバックエンドプログラミングに携わっていて、Supabaseのような最新のマネージドPostgreSQLデータベースへの移行を検討しているなら、.envファイル内の変数をいくつか変更するだけでは不十分だと気づいているはずです。接続の詳細、スキーマ、認証、ファイルストレージなど、見落としてしまうと、かなり分かりにくいエラーが発生する可能性があります。

さらに、 SupabaseをLaravelのディスクシステム(ストレージ)と統合したファイルストレージとして使用したい場合は、サービスキー、バケット、エンドポイント、カスタムFlysystemドライバなど、少し複雑になります。しかし、データベース、ストレージ、UUID処理など、すべてを非常にクリーンな方法で完全に統合できるという利点があります。

Laravel を Supabase データベースに接続する

最初のステップは、動作するLaravelプロジェクトを用意し、それをSupabaseが提供するPostgresデータベースにリンクすることです。そのためには、最新のPHPとComposerがインストールされた環境が必要で、新規プロジェクトを作成するか、既存のプロジェクトを使用できます。コンソールから、標準のLaravelコマンドを使用してプロジェクトを生成し、接続設定を開始してください。

プロジェクトのフレームワークが完成したら、通常はシンプルな認証システムを導入します。Laravel BreezeはBladeテンプレートと基本的なログイン・登録フローを備えているため、データベース接続が正しく設定されているか、ユーザーを問題なく作成できるかを迅速に検証でき、このプロセスに最適です。

接続情報を取得するには、Supabaseダッシュボードにログインし、新しいデータベースプロジェクトを作成します(`database.new`から直接作成することもできます。この操作を行うとウィザードにリダイレクトされます)。アカウントをお持ちでない場合は、まずサインアップ画面が表示されます。既にアカウントをお持ちの場合は、プロジェクト設定画面に直接進み、接続文字列が表示されるセクションが表示されます。

プロジェクトページの接続セクションに、「接続」ボタンまたはそれに類するボタンがあります。それをクリックすると、複数の接続文字列形式(URI、個々のパラメータなど)が表示されます。完全なURIをコピーしますが、デフォルトのパスワードやプレースホルダーが表示されていることが多いため、データベースで実際に使用しているパスワードに置き換えることを忘れないでください。

その情報をもとに、Laravelプロジェクトの.envファイルを開き、DB_HOST、DB_PORT、DB_DATABASE、DB_USERNAME、DB_PASSWORDの各変数を更新するか、完全な文字列形式を使用する場合はDATABASE_URL変数を設定してください。目的は、すべての設定がローカルホストではなく、Supabase Postgresクラスタを指すようにすることです。

LaravelでPostgresドライバーとSupabaseスキーマを設定する

Laravelでは、データベース設定の主要ファイルはconfig/database.phpです。フレームワークに付属のpgsqlドライバを直接使用することもできますが、Supabaseを使用する場合は、特にスキーマやPostgreSQL固有のオプションに関して、追加の設定を適用するのが一般的です。

Laravelにおける典型的なPostgresの設定は、connections配列内の「pgsql」キーの下に、次のような記述が含まれる可能性があります。

'pgsql' => ,

ここで重要なのは、 `search_path`パラメータです。Supabase はデフォルトで `public` スキーマを使用します。これは、API を通じて公開されるスキーマです。Laravel アプリケーションをそのスキーマから分離し、テーブルやポリシーの競合を回避したい場合は、前の例で示したように、`search_path` を独自のスキーマ(たとえば`laravel`)に変更することを強くお勧めします。

こうすることで、プロジェクトによって生成されるマイグレーションやテーブルは、パブリックスキーマではなく、この代替スキーマに作成されます。この分離により、不要なデータを上書きすることなく、 Supabaseパネルからのセキュリティルール、RLS、アクセス管理が大幅に簡素化され、データベース構造も整理された状態を維持できます。

  ソフトウェア開発ライフサイクル: 各段階を最適化する戦略

設定ファイルを調整したら、標準のLaravelコマンドを使用してマイグレーションを実行できます。これにより、認証テーブルと定義したその他のテーブルが作成されます。すべてが正しく設定されていれば、コマンドはSupabase Postgresサーバーに対して自動的に実行されます。

マイグレーションが完了したら、`artisan serve`コマンドで開発サーバーを起動し、ユーザーの登録とログインを試してください。接続エラーやマイグレーションエラーが表示されなければ、LaravelがSupabaseと正しく通信できているということなので、通常どおりビジネスロジックの構築を続けることができます。

Laravelで特定のSupabaseドライバーを使用する

標準のpgsqlドライバでも動作しますが、 Laravel用のsupabaseデータベースドライバを追加するパッケージがあり、PostgreSQLの動作を拡張し、特にUUID列の処理方法やクエリの構築方法に関して非常に便利な改善が施されています。

prahsys/laravel-supabase というパッケージ名で配布されているこのパッケージは、Composer を介してインストールされ、config/database.php ファイルで使用できる supabase という追加のドライバを登録します。内部的には、Laravel の Postgres ドライバをベースにしていますが、Supabase 環境向けに最適化された設定とクエリ文法が組み込まれています。

インストールが完了したら、接続セクション内で次のような記述を行うことができます。

'connections' => ,
    // otras conexiones...
],

このドライバを使用する利点は、Postgresエンジンの性能を最大限に活用できるだけでなく、特にUUIDを主キーやリレーションシップフィールドとして使用する場合など、Supabaseの細かな処理を自動的に行ってくれる点です。これにより、複雑なクエリごとに型変換を手動で記述する必要がなくなります。

このパッケージは、フレームワークとPHPの最新バージョンとの互換性も考慮して設計されており、Laravel 10.x、11.x、12.x、PHPバージョン8.1以降、そしてSupabaseを含むあらゆる標準的なPostgreSQLデータベースとの公式な互換性を提供します。

すべてが正しく動作することを確認するために、このパッケージには一連の自動テストが含まれています。テストは、速度向上のためにインメモリの SQLite データベースを使用する `composer test` コマンドで実行することも、Supabase を指す `.env.testing` ファイルを作成して `composer test-supabase` を実行し、リモートの Postgresを使用した実環境での動作を確認することもできます。

SupabaseとLaravelにおけるUUID管理

SupabaseにはUUIDカラムに関する特異な点があります。UUIDを型変換せずにテキスト文字列と直接比較しようとすると、クエリが失敗したり、予期しない結果が返されたりする可能性があります。Postgresの標準環境であれば、グローバルキャストやカスタム演算子を使ってこの問題を解決できますが、Supabaseではそのようなグローバルなカスタマイズは許可されていません。

これは、スタイルの直接クエリが次のことを意味する。

SELECT *
FROM users
WHERE id = '123e4567-e89b-12d3-a456-426614174000';

期待通りには動作しないかもしれません。ただし、明示的に型変換を行うと次のようになります。

SELECT *
FROM users
WHERE CAST(id AS TEXT) = '123e4567-e89b-12d3-a456-426614174000';

クエリは成功しました。問題は、LaravelでEloquentやクエリビルダーを使ってクエリを作成する際に、すべてのWHERE句にCASTを追加したくないということです。そこで、前述のパッケージに含まれるsupabaseドライバが登場します。このドライバは、必要なCASTを自動的に追加してくれます。

そのドライバーがアクティブになっている場合、次のような一般的なクエリを実行できます。

$user = User::find($uuidString);
$user = User::where('id', $uuidString)->first();
$users = User::whereIn('id', )->get();

直接クエリだけでなく、結合においても同様です。たとえば、投稿を取得して、UUIDフィールドを使用してユーザーテーブルと結合したい場合は、次のように記述できます。

$posts = Post::join('users', 'posts.user_id', '=', 'users.id')
    ->where('users.email', '[email protected]')
    ->get();

ドライバは、関連するUUID列に必要なテキストキャストを透過的に適用します。これにより、コードはLaravelの慣用的なスタイルを維持でき、複雑なクエリごとに生のSQLを記述したり、奇妙なトリックを使ったりする必要がなくなります。

  Python とデータベース: 初心者のための究極のガイド

UUID として扱う列をより細かく制御したい場合は、このパッケージが提供するCastsUuidColumnsトレイトをEloquent モデルで使用できます。モデル クラスでこれを使用し、追加の列の protected 配列を定義するだけです。

use Prahsys\Supabase\Traits\CastsUuidColumns;

class Post extends Model
{
    use CastsUuidColumns;

    protected $uuidColumns = ;
}

この特性は、次の3つの重要な機能を提供します。まず、プライマリキーをデフォルトのUUIDとして含めます。次に、宣言したすべての列を`$uuidColumns`プロパティに追加します。最後に、この情報をクエリビルダーに伝達し、キャストを適用する場所を知らせます。これにより、UUIDに関連するすべてのデータアクセスが一貫性を保ち、自動化されます

さらに高度なケースでは、カスタムの UUID 列検出器を登録できます。パッケージの PostgresGrammar を使用すると、列名またはクエリ コンテキストに基づいて、その列を UUID として扱うべきかどうかを判断するコールバック関数を指定できます。例:

use Prahsys\Supabase\Database\Query\Grammars\PostgresGrammar;

PostgresGrammar::detectUuidColumnsWith(function ($columnName, $query) {
    return str_contains($columnName, 'uuid_')
        || in_array($columnName, );
});

この機能を設定することで、システムは、特定のパターンを持つ名前、または特定のリストに含まれる名前を持つすべての列をUUIDとして認識し、プロジェクトの非常に具体的な命名規則に適応させることができます。

Supabase StorageをLaravelのファイルシステムとして統合する

データベースに加えて、多くのプロジェクトでは、ユーザーがアップロードした画像、ドキュメント、その他のファイルを保存する必要があります。Supabaseには、Flysystemを介してLaravelのディスクとして使用できるバケットベースのストレージサービスが含まれています。config/filesystems.php内でSupabase Storageを追加のドライバとして扱うための専用アダプタも用意されています。

このパッケージは、フレームワークのストレージシステムとシームレスに統合するFlysystemアダプタを提供します。PHP 8.1以上、Laravel 10.xおよび11.x、そしてLaravelがファイル処理に推奨するPHPファイル情報拡張機能(ext-fileinfo)という最小要件を満たしています。インストールはComposerを使用して行い、一度組み込んだら、設定ファイルでsupabaseディスクを定義するだけで済みます。

config/filesystems.phpファイルの disks 配列内に、以下のような記述を追加します。

'supabase' => ,
    ],
    'signedUrlExpires' => 60 * 60 * 24,
],

`bucket` パラメータは通常、 Supabase ダッシュボードで作成したストレージ バケットの名前です(例: `myapp-file-uploads`)。`endpoint` はプロジェクトのストレージ サービスのベース URL であり、ダッシュボードの該当セクションにも表示されます。これは通常、プロジェクトの URL とリージョンから取得されます。

`public` オプションは、バケットの内容をデフォルトで公開するかどうかを示します。`true` の場合、アダプタは特別な署名なしでアクセス可能な URL を生成します。`false` の場合、`defaultUrlGeneration` オプションが有効になり、`signedUrlExpires` で指定された有効期限を持つ署名付き URL の生成を強制できます。この設定により、扱うファイルの種類に応じてセキュリティと利便性のバランスを取ることができます。

一般的なディスクURLは通常nullのままにしておき、アダプタがエンドポイントから自動的に取得するようにします。中間プロキシまたはCDNを使用しており、生成されるルートをSupabaseのネイティブドメインではなく、そのドメインを指すようにしたい場合にのみ、このURLを変更してください。

アップロードエラーのトラブルシューティングとSupabaseストレージの鍵を理解する

LaravelからSupabase Storageにファイルをアップロードしようとした際によくある問題として、「場所: uploads/… にファイルを書き込めません」といったメッセージが表示されます。これは通常、ドライバは正しく設定されているものの、Supabaseが権限不足またはキー設定の誤りにより書き込み操作を拒否していることを示しています。

supabaseディスクの設定ファイル`config/filesystems.php`では、 `key`フィールドに「特権キー」を使用するように指定されており、読み取り専用キーは使用できないことが明示的に示されています。つまり、バケットへの書き込み権限を持つサービスキーを使用する必要があり、クライアント側の公開APIキーや変更権限のないS3互換キーでは使用できません。

Supabase パネルの「API とストレージ構成」セクションには、匿名キーとservice_role キー(またはそれに相当するもの)があり、これらは拡張された権限を持っています。SUPABASE_SECRET_ACCESS_KEY 変数には、公開キーではなく、このサービスキーを指定する必要があります。ドライバーは、env('SUPABASE_SECRET_ACCESS_KEY') を使用してこのキーを読み取ります。

  API向けのアクティブ防御および脆弱性スキャナー

ストレージ構成のS3キー、またはプロジェクトの汎用APIキーを使用してテストを行っている場合、それらの認証情報には特定のバケットへの書き込み権限がない可能性が高く、書き込みエラーが発生しています。キーの値を書き込み権限を持つ有効なサービスキーに変更し、バケットが存在し、名前が正しいことを確認することで、通常は問題が解決します。

パスワードに加えて、SUPABASE_STORAGE_BUCKETで定義されたバケットが、大文字と小文字を区別してSupabaseインターフェースで作成されたバケットと完全に一致していること、およびエンドポイントがそのストレージインスタンスの正しいURLに対応していることを確認することが重要です。余分な文字や誤ったドメインなどの些細な違いでも、アダプタがファイルの実際の保存先を特定できなくなる可能性があります。

Laravel Breeze、Blade、Supabase ストレージを使用したワークフロー

データベースとストレージの設定が完了したら、次の論理的なステップは、それらをLaravel BreezeインターフェースとBladeテンプレートに統合することです。こうすることで、ユーザーはLaravelエコシステムから離れることなく、Supabaseへの登録、認証、ファイルのアップロードを行うことができます。

コントローラー内では、 supabaseディスクを指すStorageファサードを使用します。たとえば、ファイル入力フォームから受け取ったファイルをアップロードするには、次のようなコードを使用できます。

if ($request->hasFile('file')) {
    $path = $request->file('file')
        ->store('uploads', 'supabase');
}

このコードは、Laravelに対し、 Supabaseディスクを使用し、設定されたバケット内の仮想アップロードフォルダにファイルを配置するように指示します。キーとエンドポイントが正しければ、ファイルはSupabaseストレージにアップロードされ、標準的なストレージ方法を使用してファイルのパスを取得したり、公開URLや署名付きURLを生成したりできます。

このアプローチの利点は、ローカルディスク、Amazon S3、Supabase、またはその他のサポートされているサービスなど、ストレージの用途に関わらず、アプリケーションが単一のストレージインターフェースを維持できることです。プロバイダーの切り替えは、config/filesystems.phpと環境変数を調整するだけで済み、ビジネスロジックに影響を与えることはありません。

これをBladeやBreezeと組み合わせることで、アップロードフォーム、ファイル一覧、ダウンロードリンクをアプリケーションのユーザーエクスペリエンスに完全に統合して提供できます。さらに、Supabase Storageのバケットベースおよびポリシーベースのアプローチにより、アクセス制御とセキュリティルールを活用して、各ユーザーが閲覧またはダウンロードできるコンテンツを定義できます。

パッケージ、ドライバ、設定といった一連のエコシステム全体により、LaravelはPostgresとのリレーショナルデータ、ファイルストレージ、UUID管理の両面において、Supabaseとシームレスに連携できます。キー、スキーマ、ドライバを適切に設定することで、これらのサポートレイヤーなしで両プラットフォームを手動で接続しようとした際に発生する典型的なエラーの多くを回避し、非常に堅牢な統合を実現できます。

LaravelをSupabaseと連携させてデータベースとストレージを構築し、専用のSupabaseドライバを活用してUUIDを簡単に管理し、Flysystemアダプタをストレージに使用することで、マイグレーションや認証からセキュアなバケットへのファイルアップロードまで、複雑なインフラストラクチャのすべてをLaravelのクリーンなAPIの背後にカプセル化した最新のアプリケーションを構築できます。

Laravelのブレードハスタックディレクティブ
関連記事:
LaravelのBladeディレクティブhasStackと高度なスタック制御