SupabaseはPostgresが裏側にくっついているバックエンドサービスです。Supabaseとお気に入りのフロントエンドフレームワークを持ち寄るだけで簡単にアプリが作れます。SupabaseのPostgresデータベースに保存されているデータは管理画面から簡単に閲覧することができます。
そんなSupabaseにはForeign Data Wrappersという機能があります。これは例えばStripeやFirebaseなどのSupabaseではない外部サービスのデータをさもSupabaseのテーブルの一部であるかのような感覚で取り扱える様になる機能で、管理画面から外部サービスのデータを見ることができるだけでなく、データの挿入・更新・削除もでき、また Postgres Functionsを使うことでクライアント側からもそれらのデータをSupabaseのデータと同じように取り扱うことができる様になる機能です。
今回は、そんなSupabase Wrappersを使って実際にStripeのデータでこんなことができるんだよっていうユースケースをいくつか紹介しようと思います。
前提
今回はStripeとSupabaseを繋いで色々遊んでいくのですが、その前にSupabaseとStripeに多少データが入っていないと遊びようがないですよね。実は、Stripe, Supabase, そしてNext.jsを使って簡単にSaaSアプリが構築できるテンプレートがVercelから出されています。
今回はこちらを使って一通りStripe内に商品情報や顧客情報などが入っているところからスタートしたいと思いますので、もし一緒にWrapperを触ってみたい人は一度上記の subscription starterテンプレートを触ってみてください!
StripeとSupabaseを紐付け
Supabase Wrappersを使える様になる前にまず簡単な設定が必要になります。Supabaseの管理画面からDatabase -> Wrappers
と進んで右上にある緑色のAdd wrapper
ボタンを押しましょう。いろんなwrapperの選択肢が出てきますが、今回はStripeを選びます。
次の画面でWrapper Name
はこのwrapperの内部名を与えます。今回はStripeの開発環境に試しに繋ぐということでStripe dev
と名付けましょう。Stripe Secret Key
はStripeの管理画面から取得してくるAPIキーです。
最後に追加したいテーブルを設定していきます。Add foreign table
ボタンを押してテーブルを設定していきます。
まず、stripe
というスキーマを作りましょう。そしてその中にsubscriptions
, customers
, prices
, products
を追加します。
そうするとこのようにTable Editorの画面からstripe
スキーマを覗くことで各種Stripeのデータが見える様になっていると思います。
準備が整ったので、ここからはSQLエディターに移動してそこで実際に色々クエリーを叩いてみましょう。
ユースケース1:各Supabaseユーザーに対応するStripeの顧客IDを取得する
まずは比較的シンプルな例から見てみましょう。ここではSupabaseのユーザー一覧とそれらに対応するStripeの顧客IDを引っ張ってきています。この様にWrapperを使って外部のデータを使ってSupabase内のデータとjoinすることだって可能なんです!
-- Stripeの顧客とSupabaseのユーザーを紐づけて閲覧する
select
u.id as id,
c.id as stripe_id
from auth.users u
inner join stripe.customers c
on u.id = ((c.attrs->'metadata'->>'supabaseUUID')::uuid);
ユースケース2:Stripeに新しい顧客を追加
次はWrapperを使ってStripeに新しい顧客を追加してみましょう。実際には、subscription-starterのテンプレートを使っている際はSupabase側で新規ユーザーが作成されたタイミングでStripe側の顧客が作成されるので、下記のようなコードを走らせる必要はないのですが、Wrapperを使ってデータの挿入もできちゃうんですってところを確認するためにやってみましょう。
-- Stripeに新しい顧客を追加する
insert into stripe.customers
(email)
values ('new@example.com');
以上のコードをSQLエディターで走らせてからStripeの管理画面に行くと実際に新規ユーザーが作成されているのがわかると思います。
ユースケース3:商品名を変更する
一個前の例ではinsertをしたので、今度はupdateをしてみましょう。以下のクエリーで新しい商品をStripe内に作ることができます。Supabaseのrpcを使えばクライアント側からもこちらのコードを呼び出せるのでいろいろできることの幅が広がりそうですよね!
-- Stripeの商品情報を編集する
update stripe.products
set name = 'Enterprise'
where name = 'Team';
ユースケース4:顧客の購買情報を閲覧する
最後にもう少し色々joinしている例を見てみましょう。以下のクエリーをSQLエディターで走らせると特定のSupabaseユーザーがいくらのプランを購読中かわかります。
-- 顧客の購読情報を閲覧する
select
auth.users.id as id,
prices.currency,
prices.unit_amount
from auth.users
inner join stripe.customers
on users.id = ((customers.attrs->'metadata'->>'supabaseUUID')::uuid)
inner join stripe.subscriptions
on customers.id = subscriptions.customer
inner join stripe.prices
on subscriptions.attrs->'plan'->>'id' = prices.id
where users.id = 'a1807997-0e7a-4954-9557-0a2c66d69380'::uuid; -- ここには実在する特定のSupabaseユーザーのユーザーIDを入れる
この様にこのユーザーは$500のプランを購読中であることがわかります。
まとめ
今回はSupabaseのForeign Data Wrapperで遊んでみるをテーマにStripeとsupabaseを繋げていろんな形で双方のデータとやり取りをしてみました。Foreign data wrapperを使うとあまりAPIを意識せずに複数サービスを繋げたサービスが構築できそうですね!ぜひ皆さんもいろいろ試してみてください!