Loading...

2023-11-29(水) 15:00

😊 SupabaseのDatabase FunctionでPOSTリクエストを送信してEdge Functionを実行する

Supabase
SupabaseのDatabase Functionの中でHTTP POSTリクエストを送信することでEdge Functionを実行する方法を解説します。なお、Edge Function以外にもHTTP POSTリクエストを受け付けるAPIなどにも当然ながら使用できます。

目次

前提と注意事項

  • Supabase アカウントを作成済みであること
  • Supabase のプロジェクトを作成済みであること
  • 拡張機能pg_nethttpの違いについては説明していません。

この記事では以下の公式ドキュメントを参考にします。

http: RESTful Client

The http extension allows you to call RESTful endpoints within Postgres.

supabase.com

この記事のゴール

Supabase の Database Function の中で HTTP POST リクエストを送信し、指定した Supabase Edge Function を実行できるようになることがこの記事のゴールです。

http 拡張機能を有効化する

まずはじめに、Supabase でpc_cronを使えるようにするために有効化する必要があります。 以下のように Supabase の Web 管理画面のサイドメニューにある「Database」ページの「Extensions」ページで、pg_cronと検索します。そして以下のように表示されたpg_cronのスイッチを ON にします。

Supabaseのhttp拡張機能

ON にすると以下のように確認ダイアログが開くので、Enable extensionボタンをクリックします。
Select a schema to enable the extension forについては、extensionを選択します。

Supabaseのpg_cronを有効化する

以下のように ON になりました。これで HTTP リクエストを送信するための拡張機能が有効化されました。 以上で拡張機能httpの有効化が完了です。

拡張機能 http を使って POST リクエストを送信する Database Function を作成する

拡張機能httpを実行する Database Function をinvoke_edge_function_using_httpという名前で作成します。 以下は、実行したい Supabase Edge Function にユーザー名とメールアドレスを POST リクエストで送信する例ですが、POST リクエストで送る内容は各自が実行したい Supabase Edge Function(もしくは他の API など)に合わせて変更してください。

Edge Functionを実行するためのDatabase Function
--
-- Edge Functionを実行するためのDatabase Function
--
DROP FUNCTION IF EXISTS public.invoke_edge_function_using_http;
CREATE OR REPLACE FUNCTION public.invoke_edge_function_using_http()
 RETURNS TABLE(_status text, _content jsonb)
 LANGUAGE plpgsql
 SECURITY DEFINER
 SET search_path TO 'public', 'extensions', 'vault'
AS $function$
DECLARE
  vault_anon_key TEXT;
  response RECORD;
  body_data TEXT;
  edge_function_url TEXT := 'https://xxxxxxxxxxxxxx.supabase.co/functions/v1/my-edge-function';
BEGIN
  -- anon key をVaultから取得し、vault_anon_keyに格納する
  SELECT decrypted_secret
  INTO vault_anon_key
  FROM vault.decrypted_secrets
  WHERE name = 'anon_key';
 
  -- POSTリクエストのbodyデータ
  body_data := '{"record": {"nickname": "Email from Database function", "email": "[email protected]"}}';
 
  -- Edge FunctionをHTTP POSTリクエストで呼び出す
  SELECT status::text, content::jsonb
  INTO response
  FROM http((
          'POST',
           edge_function_url,
           ARRAY[http_header('Authorization', 'Bearer ' || vault_anon_key), http_header('Content-Type', 'application/json')],
           'application/json',
           coalesce(body_data, '') -- body_data が NULLの場合は空のボディを送信する
        )::http_request);
 
  -- レスポンスが NULL である場合はエラーとする
  IF response.content IS NULL THEN
    RAISE EXCEPTION 'Error: content is NULL. Status: %', response.status;
  ELSE
    RAISE LOG 'LOG: Edge Function executed. Status: %', response.status;
  END IF;
 
  -- HTTP POSTリクエスト結果のステータスと内容を返す
  RETURN QUERY SELECT response.status, response.content;
END;
$function$;

あとは上記のinvoke_edge_function_using_httpを好きなところで実行すれば、Supabase の Database Function の中で Edge Function を実行できます。
以下は試しに Supabase の Web 管理画面にあるSQL Editorselect文で実行した例です。

Database FunctionからEdge Functionを実行しれ例

以下のようなレスポンスを返すようにしてします。

レスポンス
(200,"{""id"": ""201e5ee3-08c3-474f-858a-129749da89b0""}")

HTTP ステータスとして200、その後に続く"{""id"": ""201e5ee3-08c3-474f-858a-129749da89b0""}"は実行した Supabase Edge Function からの応答内容です。


なお、上記では Supabase Vault を使って API キーを取得しています。Supabase Vault の使い方については以下にまとめています。

🗄️ SupabaseのVaultを使ってシークレットを保存、使用する

SupabaseのVaultを使ってシークレット(APIキー、環境変数など)を保存し、Database Function内で使用する方法を解説します。

ritaiz.com

まとめ

この記事では、Supabase Edge Function を Supabase の Database Function 内で呼び出して実行する方法を解説しました。
拡張機能のhttpは当然ながら Supabase Edge Function 以外にも使用でき、POST 以外にも GET、PUT、DELETE リクエストのいずれも送信できます。