🌱

新卒1年目でSupabaseデビューした話

はじめに

皆さんこんにちは、熊本でエンジニアをしているハラダです。新卒1年目の僕が実務で「Supabase」を使用したので、感想を共有したいと思います。

Supabaseとは?
https://supabase.com/

Supabaseは、主にバックエンドの機能を提供するプラットフォームです。
オープンソースで多くのバックエンド機能を提供しており、Firebaseの代替として利用されます。
具体的には、以下の機能を提供しています:
・ データベースの管理
・ リアルタイムのデータ同期
・ 認証機能
・ ストレージ
・ エッジ処理
これらの機能を利用することで、開発者は簡単にアプリケーションのバックエンドを構築することができます。

使用した技術スタックは、Next.js,TypeScript,Supabaseです。

つまづいたところ

1. PL/pgSQLのログ

変数の値が見たいと思った時、フロントエンドではconsole.logを使えば変数の値が見れますが、PL/pgSQLの変数の値を見るにはどうしたら良いか分かりませんでした。

RAISE WARNINGを関数内で使うことで、ログを出すことができました。

PL/pgSQL
~
BEGIN
RAISE WARNING 'メッセージ %', new;
~
dockerのsupabase_db_〇〇イメージのlogs
postgres@postgres CONTEXT: PL/pgSQL function 関数名() line 3 at RAISE
postgres@postgres WARNING: メッセージ ここに値が出力される

2. 読み込み速度の高速化

あるデータの読み込みと表示までに5.8秒ほどかかっていました。原因はリレーションが多すぎることだと仮定を立てました。
Postgresにマテリアライズドビューという機能があります。SQL文のSELECT結果をキャッシュし実体として保持します。つまり、一時的なテーブルを作成できます。
https://www.postgresql.jp/document/15/html/sql-creatematerializedview.html
これにより5.8秒前後かかっていた処理時間を、0.5秒まで短縮することができました。
マテリアライズドビューの作成のため既存のSupabase Clientから実行されたSQLの実行ログを取得する必要がありました。下記クエリで取得できます。

SQLエディター
select query from pg_stat_statements where query like '%テーブル名%'

取得したSQL文はJoinのON句を修正する必要がありました。一対多の場合はON trueに変更しました。多対多の場合はON句のカラム名を修正しました。
マテリアライズドビューはそのままではデータが古くなってしまうので、元となったテーブルのデータが変更になるたびに更新が必要になります。まずはマテリアライズドビューを更新するPostgresのfunctionを作成します。

PL/pgSQL
CREATE OR REPLACE FUNCTION refresh_materialized_view()
RETURNS void
LANGUAGE plpgsql
security definer
set search_path = public
AS $$
BEGIN
    REFRESH MATERIALIZED VIEW public.materialized_view;
END;
$$;

その後、rpcにてfunctionを呼び出します。

呼び出し元
supabaseClient.rpc('refresh_materialized_view')

3. Supabaseのドキュメント

ドキュメントを読み慣れてない僕は、読んでも頭に入ってこず、かなり苦戦しました。
例えば、update a userが2つあるのは紛らわしく、どちらを使えば良いか悩みました。

管理者権限で更新する場合👇

ユーザー権限で更新する場合👇

また、ドキュメントに例文も記載してほしいと感じる事例がありました。DBのテーブルをリレーションで繋ぐ際、ユーザー削除時に論理削除が必要でしたが、正しくは以下の通り書くべきところを、間違えて下記の通り書いてしまいました。

正しい例
const { data, error } = await supabase.auth.admin.deleteUser(
  '715ed5db-f090-4b8c-a067-640ecee36aa0',
  true
)
誤った例
const { data, error } = await supabase.auth.admin.deleteUser(
  '715ed5db-f090-4b8c-a067-640ecee36aa0',
  {shouldSoftDelete: true}
)

感想

Supabaseを実際に使ってみると多機能で驚きました。
ローカルのSQL Editorで構文ミスすると画面がクラッシュしてSQLのエラー文が表示されるなど使いづらい部分もあります。しかし、DBに加えて認証機能やRLSなどの便利な機能が無料で利用できるのは他にはない強みです。

無料の機能でも個人開発には十分ですし、今後もSupabaseを活用していきたいです。(日本語版のドキュメントが作成されるとさらに嬉しいですね)

今回初めてマテリアライズドビューを使いましたが、ここまでパフォーマンスに影響があるとは思っていませんでした。この経験を糧に、プログラミングの技術向上に努めたいです。

Arsaga Developers Blog

Discussion