iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0
Software Development

我獨自開發 - 用 Supabase 打造全端應用系列 第 15

第十五關 - 影子軍團:Supabase Edge Functions

  • 分享至 

  • xImage
  •  

封面

什麼是 Edge Functions?

Supabase Edge Functions 是一個基於 Deno 運行時的無伺服器函數服務,可以在邊緣節點執行,TypeScript/JavaScript 程式碼。這些函數會在全球各地的邊緣伺服器上運行,確保低延遲和高效能。

簡單來說

想像 Edge Functions 就像是何振宇的「影子軍團」:

  • 就近服務:這個助手在世界各地都有分身,用戶在哪裡,就從最近的地方提供服務
  • 隨叫隨到:需要的時候立即啟動,不用的時候自動休眠,不浪費資源
  • 安全可靠:敏感的商業邏輯在雲端執行,前端只需要呼叫即可
  • 無限擴展:無論有多少用戶同時使用,都能自動應對

為什麼要使用 Edge Functions?

傳統後端開發的挑戰

  • 伺服器管理:需要維護伺服器、處理擴展、監控效能
  • 部署複雜:設定 CI/CD、管理環境變數、處理版本更新
  • 成本考量:即使沒有流量也要支付伺服器費用
  • 地理限制:伺服器通常只在特定地區,遠距離用戶體驗較差

Edge Functions 的優勢

  • 零維護:不需要管理伺服器,專注於程式邏輯
  • 全球部署:自動在全球邊緣節點部署,提供最佳效能
  • 按需付費:只有在函數執行時才收費,沒有固定成本
  • 快速開發:支援 TypeScript,整合 Supabase 生態系統

如何使用 Edge Functions

方法一:CLI 方式建立

1. 建立新的 Edge Function

# 建立名為 hello-world 的函數
supabase functions new hello-world

這會在 supabase/functions/hello-world/index.ts 建立一個基本的函數模板:

import 'jsr:@supabase/functions-js/edge-runtime.d.ts';

console.log('Hello from Functions!');

Deno.serve(async req => {
  const { name } = await req.json();
  const data = {
    message: `Hello ${name}!`,
  };

  return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json' } });
});

2. 本地測試函數

# 啟動本地開發環境
supabase start

# 在另一個終端機中提供函數服務
supabase functions serve hello-world

3. 測試函數呼叫

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

4. 部署到雲端

# 部署函數
supabase functions deploy hello-world

# 部署到雲端特定專案
supabase functions deploy hello-world --project-ref your-project-ref

方法二:Dashboard 方式建立

1. 進入 Supabase Dashboard

  • 登入你的 Supabase 專案
  • 點選左側選單的「Edge Functions」

2. 建立新函數

  • 點擊「Deploy a new function」
  • 選擇「Via Editor」的「Simple Hello World」模板或從空白開始,也有「Via AI Assistant」選項可以使用 AI 助手協助建立函數,真的很貼心!
  • 輸入函數名稱(例如:hello-world

3. 編寫函數程式碼

在線上編輯器中輸入:

import 'jsr:@supabase/functions-js/edge-runtime.d.ts';
interface reqPayload {
  name: string;
}

console.info('server started');

Deno.serve(async (req: Request) => {
  const { name }: reqPayload = await req.json();
  const data = {
    message: `Hello ${name}!`,
  };

  return new Response(JSON.stringify(data), {
    headers: { 'Content-Type': 'application/json', Connection: 'keep-alive' },
  });
});

4. 部署函數

  • 點擊「Deploy function」
  • 等待部署完成

5. 測試函數

在 Dashboard 的測試區域中(點擊進入剛剛建立的函數內頁,右上角「Test」):

{
  "name": "World"
}

在前端呼叫 Edge Function

import { createClient } from '@supabase/supabase-js';

const supabase = createClient('YOUR_SUPABASE_URL', 'YOUR_SUPABASE_ANON_KEY');

// 呼叫 hello-world 函數
const { data, error } = await supabase.functions.invoke('hello-world', {
  body: { name: 'World' },
});

if (error) {
  console.error('Error:', error);
} else {
  console.log('Response:', data);
}

日誌管理與除錯

在開發和維護 Edge Functions 時,如何正確查看錯誤資訊:

這個技巧在除錯 API 呼叫、驗證授權 token 或檢查請求格式時非常有用。

# 查看本地函數日誌
supabase functions serve --debug

Supabase Dashboard 日誌查看:

  1. 登入 Supabase Dashboard
  2. 選擇你的專案
  3. 在左側選單點選「Edge Functions」
  4. 選擇要查看的函數
  5. 點選「Logs」標籤頁查看執行日誌和錯誤資訊

除錯技巧:

  • 使用 console.log() 在函數中輸出除錯資訊
  • 檢查函數的回傳格式是否正確(必須是 Response 物件)
  • 確認環境變數是否正確設定
  • 查看 Dashboard 中的詳細錯誤堆疊資訊
// supabase/functions/hello-world/index.ts
Deno.serve(async req => {
  const headersObject = Object.fromEntries(req.headers);
  const headersJson = JSON.stringify(headersObject, null, 2);
  console.log(`Request headers:\n${headersJson}`);

  try {
    const { name } = await req.json();

    // 記錄處理訊息
    console.log(`Processing request for: ${name}`);

    const data = {
      message: `Hello ${name || 'World'}!`,
    };

    return new Response(JSON.stringify(data), {
      headers: { 'Content-Type': 'application/json' },
    });
  } catch (error) {
    // 記錄錯誤訊息
    console.error(`Request processing failed: ${error.message}`);
    return new Response(JSON.stringify({ error: 'Internal Server Error' }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
});

刪除 Edge Function

當你不再需要某個函數時,需要完整清理相關檔案和配置:

# 方法一:使用 CLI 刪除
supabase functions delete hello-world

# 方法二:手動刪除
# 1. 刪除函數資料夾
rm -rf supabase/functions/hello-world

# 2. 清理配置檔案(檢查 supabase/config.toml)
# 移除函數相關的配置項目

# 3. 重新啟動本地環境
supabase stop
supabase start

提醒:

  • 如果只刪除資料夾而沒有清理配置檔案,可能會導致 Supabase 啟動失敗
  • 建議優先使用 supabase functions delete 指令,它會自動處理相關清理工作
  • 刪除雲端函數前請確認沒有其他服務依賴該函數

小結

後續會使用 Edge Functions 建立更複雜的應用場景,像是整合 Resend 信件發送、第三方 API 整合等。

... to be continued

有任何想討論歡迎留言,或需要指正的地方請鞭大力一點,歡迎訂閱、按讚加分享,分享給想要提升開發效率的朋友~


上一篇
第十四關 - 惡魔城的鑰匙:Supabase Storage
下一篇
第十六關 - 心靈感應與雙向感知:Supabase Realtime
系列文
我獨自開發 - 用 Supabase 打造全端應用16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言