開発・個人開発

Supabase Edge Functionsの基礎 サーバーレスAPIをDenoで作る

Supabase Edge Functionsの基礎 サーバーレスAPIをDenoで作る

この記事の要点

Supabase Edge FunctionsはDenoで動くサーバーサイドの関数で、APIキーを隠したバックエンド処理・外部API連携・データベースの管理操作に使える。セットアップから実装・デプロイまでを解説する。

結論

Supabase Edge FunctionsはAPIキーを隠したバックエンド処理を実装する最も手軽な方法だ。フロントエンドから直接使いたくない処理(メール送信・外部API呼び出し・管理操作)をEdge Functionsに集約することで、セキュアなアーキテクチャを作れる。セットアップはSupabase CLIで数分で完了する。

Supabase Edge Functionsを使う場面

フロントエンドのJavaScriptから直接行うと問題になる処理をEdge Functionsで代替する。

典型的なユースケース

  • メール送信(Resend・SendGrid等のAPIキーを隠す)
  • Slack通知(Webhook URLを隠す)
  • 外部AIサービスの呼び出し(OpenAI・Anthropic APIキーを隠す)
  • Supabaseのservice_role keyを使った管理操作
  • WebhookのHTTPエンドポイント(GitHubやStripeからの通知受信)

フロントエンドのコードにAPIキーを含めると、ブラウザのデベロッパーツールで誰でも確認できる。Edge Functionsに処理を移すことで、APIキーをサーバーサイドの環境変数として管理できる。

セットアップ

1. Supabase CLIのインストール

npm install -g supabase

2. ログイン

supabase login

ブラウザが開いて認証する。

3. プロジェクトとの連携

# プロジェクトのルートディレクトリで実行
supabase init

# リモートプロジェクトに連携(プロジェクトIDはSupabaseダッシュボードで確認)
supabase link --project-ref your-project-id

最初のEdge Functionを作る

supabase functions new hello

supabase/functions/hello/index.tsが作成される。

import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
};

serve(async (req) => {
  // CORSのプリフライトリクエストに対応
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders });
  }

  const { name } = await req.json();
  const greeting = `Hello ${name || 'World'}!`;
  
  return new Response(
    JSON.stringify({ message: greeting }),
    {
      headers: {
        ...corsHeaders,
        'Content-Type': 'application/json',
      },
    }
  );
});

ローカルでのテスト

supabase functions serve hello

別のターミナルでテストリクエストを送る:

curl -i --location --request POST 'http://localhost:54321/functions/v1/hello' \
  --header 'Content-Type: application/json' \
  --data '{"name": "Taro"}'

{"message": "Hello Taro!"}が返ってきたら成功だ。

環境変数の設定

APIキーなどの機密情報はSupabaseのsecretsとして管理する。

# ローカル用の環境変数(.envに書く)
RESEND_API_KEY=re_xxxxxxxxxxxx
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...

# Supabaseにシークレットをデプロイ
supabase secrets set RESEND_API_KEY=re_xxxxxxxxxxxx
supabase secrets set SLACK_WEBHOOK_URL=https://hooks.slack.com/...

# Deno側での読み取り
const resendApiKey = Deno.env.get('RESEND_API_KEY');

SUPABASE_URLSUPABASE_SERVICE_ROLE_KEYはEdge Functions内で自動的に利用可能なため、設定不要だ。

データベースへのアクセス

Edge Functions内からSupabaseのデータベースにアクセスするには、service_role keyを使う。これにより、RLSをバイパスして管理者権限での操作が可能になる。

import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const supabase = createClient(
  Deno.env.get('SUPABASE_URL')!,
  Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
);

// データの取得
const { data, error } = await supabase
  .from('inquiries')
  .select('*')
  .order('created_at', { ascending: false });

// データの挿入
await supabase.from('page_views').insert({ slug: 'my-article' });

デプロイ

supabase functions deploy hello

デプロイが完了すると、https://your-project.supabase.co/functions/v1/helloでアクセスできるようになる。

フロントエンドからの呼び出し

AstroやNext.jsのクライアントサイドコードからEdge Functionを呼び出す。

const res = await fetch(
  `${import.meta.env.PUBLIC_SUPABASE_URL}/functions/v1/hello`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${import.meta.env.PUBLIC_SUPABASE_ANON_KEY}`,
    },
    body: JSON.stringify({ name: 'Taro' }),
  }
);

const data = await res.json();
console.log(data.message); // "Hello Taro!"

Edge Functionsの実用的な活用例は問い合わせフォームをSupabase+Resend+Slackで作るで、Supabaseの基本セットアップはSupabaseの始め方で解説している。

まとめ

Supabase Edge Functionsは、APIキーを含む外部サービスとの連携・サービス間の処理をサーバーサイドで安全に実行できる仕組みだ。Supabase CLIでプロジェクトを初期化し、functions newでファイルを作成、functions serveでローカルテスト、functions deployでデプロイという流れで数分で動かせる。CORSの設定とsecretsによる環境変数管理を最初に整えておくことで、以降の開発が快適になる。

よくある質問

Supabase Edge Functionsとは何ですか

Supabaseが提供するサーバーレス関数の実行環境で、TypeScript/JavaScriptで書いたコードをDenoランタイムで実行できます。フロントエンドから直接呼び出すAPIエンドポイントを作成したり、データベース操作に連動した処理(トリガー)を実装したりするのに使います。

Supabase Edge Functionsは無料で使えますか

Freeプランでは月50万回の呼び出し・月10GBのメモリ使用量まで無料です。個人開発のAPIエンドポイントとして使う場合は無料枠内で十分なケースがほとんどです。

Supabase Edge FunctionsとVercel Edge Functionsの違いは何ですか

どちらもサーバーサイドで関数を実行するサービスですが、Supabase Edge FunctionsはSupabaseのデータベース・Auth・Storageと連携しやすく、Supabaseを使ったプロジェクトに向いています。Vercel Edge FunctionsはNext.js・Astroなどのフロントエンドフレームワークと統合しやすい点が特徴です。

Node.jsの知識があればSupabase Edge Functionsを使えますか

TypeScript/JavaScriptの基礎知識があれば使えます。DenoはNode.jsと同じJavaScriptランタイムですが、モジュールのimportの書き方(URLベース)と一部のAPIが異なります。Node.jsからの移行時に主に変わる点はpackage.jsonがない・npm installが不要・importはURLで行うことです。