こんにちは!代表取締役 兼 AIサービス開発室の鈴木生雄です。
前回の記事では、Shoelogのシステム構成とアプリ内部のアーキテクチャを紹介しました。今回はその構成図に登場したバックエンドサービス「Supabase」を深掘りします。
実を言うと、Supabaseは今回の開発で初めて触れた技術です。iPhoneアプリ開発が未経験だったのと同じく、Supabaseの知識もゼロからのスタートでした。それでも週末の細切れ時間だけでバックエンドを構築できてしまったのは、Supabaseというサービスのカバー範囲の広さと、コーディングエージェントの実装力の掛け算によるものだと思っています。
Supabaseとは
Supabaseは、データベース、利用者認証、ファイル保存およびサーバー側プログラムの実行環境を統合して提供するBackend as a Service(BaaS)です。
本来、これらを自前で用意しようとすると、サーバーを立てて、データベースをインストールして、認証基盤を構築して……と、アプリ本体の開発になかなか着手できません。BaaSを使えば、この「土台作り」を丸ごとスキップして、アプリ固有の開発に集中できます。個人の週末開発にとっては、これは死活問題級のメリットです。
Shoelogでは、Supabaseが提供する機能のうち、次の4つを使用しています。
- Supabase Auth:利用者の認証・認可
- PostgreSQL:構造化されたデータの保存
- Supabase Storage:写真の保存
- Supabase Edge Functions:管理者権限を必要とする処理の実行
以下、順番に紹介していきます。
Supabase Auth:認証基盤をお任せする
Supabase Authは、Supabaseが提供するユーザー認証・認可のためのマネージドサービスです。メールアドレスとパスワードによる認証に加え、AppleやGoogleなどの外部プロバイダーを利用したソーシャルログインにも対応しています。SDKを通じてセッションの保持や更新も自動的に行われるため、開発者は少ない実装量で安全な認証基盤を構築できます。
Shoelogでは、Appleが提供するSign in with AppleとSupabase Authを連携させることで認証・認可を実装しています。この連携の仕組みはそれ自体が面白いテーマなので、次回たっぷり紹介します。今回は「認証はSupabase Authが受け持っている」とだけ押さえておいてください。
PostgreSQL:データ管理の主役
PostgreSQLは、30年以上の開発の歴史を持つオープンソースのリレーショナルデータベース管理システム(RDBMS)で、Supabaseでは標準のデータベースとして採用されています。業務システムの開発に携わっている方にはおなじみのデータベースですね。当社の開発案件でもよく登場します。趣味アプリの裏側が実は業務システムと同じデータベースで動いている、というのは個人的に気に入っているポイントです。
Shoelogの文字、数値、日付などのデータは、このPostgreSQLに保存しています。主要なテーブルは次のとおりです。
- shoes:靴の基本情報
- shoe_photos:靴写真の管理情報
- wear_logs:着用記録
- care_logs:お手入れ記録
- entitlements:有料プランの利用状態
- notification_settings:お手入れ通知の設定

前回紹介した5つの機能(靴管理、着用記録、お手入れ記録、統計表示、SNS連携)が、ほぼそのままテーブル構成に対応していることがお分かりいただけるかと思います。
Row Level Security:データベース側の最終防衛ライン
さて、今回の記事で一番お伝えしたいのがこの話です。ShoelogではPostgreSQLのRow Level Security(RLS)を活用しています。
RLSとは、テーブルごとに定義したポリシーに基づき、データベースの行単位でアクセス可否を制御する仕組みです。
もちろんShoelogでは、iPhoneアプリ側でも、ログイン状態や契約状態に応じて画面および操作の可否を制御し、認証中の利用者に対応する利用者IDを付与してSupabaseへ送信しています。「アプリ側で制御しているなら、それで十分では?」と思われるかもしれません。
しかし、利用者の端末上で動作するアプリ側の制御は、プログラムの改変やAPIへの直接アクセスによって回避される可能性があります。端末の中で動くプログラムは、極論すれば利用者(あるいは攻撃者)の支配下にあるのです。このため、最終的なアクセス可否は、SupabaseのRLSによってデータベース側で確認しています。
具体的には、各テーブルに利用者を識別するuser_id列を保持し、認証中の利用者IDと一致する場合に限り、参照、登録、更新および削除を許可しています。これにより、アプリ側の不具合や不正なリクエストが発生した場合でも、他の利用者のデータへのアクセスをデータベース側で拒否できます。
「クライアントを信用せず、サーバー側で守りを固める」。これはWebシステムでも業務システムでも変わらない鉄則ですが、個人開発の趣味アプリであっても、他人様のデータをお預かりする以上は手を抜けないところです。
Supabase Storage:写真の置き場所
Supabase Storageは、画像や動画、ドキュメントなどのファイルを保存・配信するためのオブジェクトストレージサービスです。ファイルはバケットと呼ばれる単位で管理され、AWS S3互換のAPIを通じてアップロードやダウンロードを行えます。
Shoelogでは、靴やお手入れ記録に添付する写真は、PostgreSQLのテーブルに画像データそのものを保存するのではなく、Supabase Storageにファイルとして保存しています。データベースには、写真がStorage内のどこに存在するかを示すパスと、メイン写真であるかなどの管理情報のみを保存します。
このように、検索やデータ同士の関連付けに適したデータベースと、大容量ファイルの保存に適したStorageを使い分けています。
Supabase Edge Functions:アプリに持たせてはいけない処理の置き場所
Supabase Edge Functionsは、Supabaseが提供するサーバーレスの関数実行環境です。TypeScriptで記述した処理をサーバー側で動作する関数としてデプロイでき、サーバーの構築や運用は不要で、HTTPリクエストを契機に必要なときだけ実行されます。
Shoelogでは、通常のデータ登録や参照は、ログインした利用者の権限でiPhoneアプリから実行しています。一方、有料プランの購入処理や利用者アカウントの削除といった管理者権限を必要とする処理は、iPhoneアプリには実装できません。管理者用の秘密鍵をアプリに格納すると、解析によって外部に漏えいするおそれがあるためです。
そこで、これらの処理はEdge Functionsに実装しています。秘密鍵などの機密情報をクライアントから切り離してサーバー側に保持できるため、管理者権限を伴う処理や外部APIとの連携など、アプリ側に実装すべきでないロジックの実行場所として適しているのです。
先ほどのRLSと合わせて、「アプリ(クライアント)に任せてよいこと」と「サーバー側で守るべきこと」の線引きが、バックエンド設計の勘所だと言えます。
次回予告
次回は、今回さらっと流した「認証」を深掘りします。Shoelogの認証方式として採用したSign in with Appleの紹介と、Face IDでの本人確認からSupabaseのセッション発行まで、ログインの裏側で何が起きているのかをシーケンス図とともに解説する予定です。お楽しみに!
