什麼是 Supabase? – 深度分析

什麼是 Supabase?從入門到實作的完整指南

引言:現代化應用開發的新選擇

在當今快速變化的網路世界中,開發者們總是尋求更高效、更靈活的工具來加速應用程式的開發。傳統上,建立一個完整的應用程式需要前端、後端、資料庫、認證系統、檔案儲存等多個獨立的服務。這不僅增加了開發的複雜性,也拉長了專案的週期。

近年來,「後端即服務」(Backend as a Service, BaaS)的概念應運而生,它將這些常用的後端功能打包成一套可直接使用的服務,讓開發者能更專注於前端使用者體驗。其中,Google 的 Firebase 便是 BaaS 領域的佼佼者。然而,對於那些尋求開源、更強大資料庫彈性或不想被特定供應商鎖定的開發者來說,市場上一直存在著對替代方案的需求。

這正是 Supabase 嶄露頭角的原因。Supabase 是一個開源的 Firebase 替代品,它以 PostgreSQL 資料庫為核心,提供了一整套強大的後端服務,包括自動生成的 API、即時訂閱、使用者認證、檔案儲存和邊緣函式等。本文將帶您深入了解 Supabase 的世界,從其核心概念到實際操作,一步步引導您利用 Supabase 建立您的應用程式。

什麼是 Supabase?深入了解其核心

Supabase 是一個將多個開源工具整合在一起的 BaaS 平台,旨在提供一個完整的後端解決方案。它的理念是讓開發者能夠使用熟悉的 SQL 語言來管理資料,同時享受現代化後端服務的便利性。

BaaS (Backend as a Service) 的概念

BaaS 是一種雲端服務模型,它提供預建的後端功能,如資料庫管理、使用者認證、檔案儲存、推播通知等,讓開發者無需從頭開始建構和維護這些複雜的後端基礎設施。這使得開發者可以專注於應用程式的前端邏輯和使用者體驗,從而大大加快開發速度。

Supabase 的核心組成

Supabase 的設計哲學是「開源優先」和「以 PostgreSQL 為核心」。它巧妙地將多個開源專案整合起來,為開發者提供一致且強大的開發體驗:

  1. PostgreSQL 資料庫: Supabase 的基石。它提供了一個強大、可靠且功能豐富的關聯式資料庫。開發者可以利用所有 PostgreSQL 的特性,包括儲存過程、觸發器、視圖等,並且可以使用標準 SQL 語句進行操作。
  2. 自動生成 API (PostgREST): 當您在 Supabase 中建立資料表時,它會自動為您的資料庫生成一個 RESTful API。這個 API 允許您透過 HTTP 請求來執行資料的增、刪、改、查操作,無需手動編寫後端 API 邏輯。此外,它也支援 GraphQL 查詢 (透過 pg_graphql 或整合 Hasura)。
  3. 即時訂閱 (Realtime): Supabase 內建了即時功能,允許客戶端訂閱資料庫的變更。當資料庫中的資料發生變化時(例如新增、更新或刪除),所有訂閱的客戶端都會即時收到通知,這對於建立聊天應用程式、即時儀表板或協作工具非常有用。

Supabase 與 Firebase 的比較

特性 Supabase Firebase
核心資料庫 PostgreSQL (關聯式) Cloud Firestore (NoSQL 文件型)
API 類型 RESTful API (自動生成), GraphQL SDK 直接操作
開源狀態 開源 閉源
資料庫模型 關聯式,支援 SQL NoSQL,JSON 文件模型
自託管 支援自託管 不支援自託管
靈活性 高,可使用 SQL 擴展,整合其他開源工具 較低,依賴 Google 生態系統
學習曲線 熟悉 SQL 者較快上手 熟悉 NoSQL 概念者較快上手
主要優勢 開源、SQL 靈活性、強大的關聯式資料處理 Google 生態整合、易於擴展、NoSQL 彈性

Supabase 的主要功能模組

Supabase 不僅僅是一個資料庫,它是一個完整的後端生態系統,提供了開發者所需的各種服務:

1. 資料庫 (Database)

  • 基於 PostgreSQL: 提供一個功能強大的關聯式資料庫,支援 SQL 查詢、儲存過程、觸發器、視圖等。您可以透過 Supabase 儀表板或任何 PostgreSQL 客戶端進行管理。
  • 資料表編輯器: 直觀的儀表板介面,讓您可以輕鬆建立、編輯和管理資料表、欄位和資料。
  • 行級安全 (Row Level Security, RLS): 一項強大的安全功能,允許您在資料庫層級定義精細的資料存取權限,確保使用者只能看到或修改他們有權限的資料。

2. 認證 (Auth)

  • GoTrue 服務: Supabase 使用 GoTrue 來處理使用者認證。它支援多種認證方式,包括:
    • 電子郵件/密碼 (Email/Password)
    • 魔法連結 (Magic Link)
    • 第三方 OAuth 供應商 (Google, GitHub, Facebook, Apple 等)
  • JWT (JSON Web Tokens): 認證成功後會返回 JWT,用於安全地驗證使用者身份和授權。
  • 使用者管理: 在儀表板中可以方便地管理使用者,包括啟用、禁用或刪除使用者。

3. 儲存 (Storage)

  • 物件儲存: 提供一個可擴展的儲存服務,用於儲存和管理檔案,如圖片、影片、文件等。
  • 權限控制: 透過儲存策略 (Storage Policies) 和 RLS,您可以精確控制哪些使用者可以存取哪些檔案。
  • CDN 整合: 支援內容交付網路 (CDN) 以加速檔案的傳輸。

4. 邊緣函式 (Edge Functions)

  • 無伺服器函式: 允許您在 Supabase 專案中部署輕量級的無伺服器函式。這些函式在邊緣節點運行,響應速度快,適合處理後端邏輯、資料轉換或與第三方服務整合。
  • 基於 Deno: 使用 Deno 執行環境,支援 TypeScript 開發,提供現代化的開發體驗。

5. 即時 (Realtime)

  • WebSocket 訂閱: 透過 WebSocket 協議,客戶端可以訂閱資料庫中特定資料表的變更。當資料發生新增、更新或刪除時,客戶端會立即收到通知,實現即時同步。
  • 廣播功能: 除了資料庫變更,Realtime 服務也支援頻道廣播,可用於建立聊天室或即時通知系統。

實作步驟:從零開始建立 Supabase 專案

現在,讓我們透過實際操作來體驗 Supabase 的強大功能。

步驟 1:註冊並建立 Supabase 專案

  1. 前往 Supabase 官網: 訪問 https://supabase.com/
  2. 註冊帳號: 您可以使用 GitHub 帳號快速註冊或使用電子郵件註冊。
  3. 建立新專案: 登入後,點擊「New project」按鈕。您需要填寫以下資訊:
    • Name: 您的專案名稱 (例如:my-todo-app)。
    • Database Password: 設定一個強密碼,這是您資料庫的超級使用者密碼。
    • Region: 選擇一個離您或您的使用者最近的地區。
    • Pricing Plan: 選擇免費方案 (Free Plan) 即可。
  4. 等待專案初始化: Supabase 會自動為您部署所有必要的服務,這可能需要幾分鐘的時間。

步驟 2:建立資料表

專案建立完成後,您將進入 Supabase 儀表板。讓我們建立一個簡單的 todos 資料表來管理待辦事項。

  1. 導航至資料庫: 在左側導覽列中,點擊「Table Editor」圖示。
  2. 建立新表: 點擊「New table」按鈕。
  3. 配置資料表:

    • Name: todos
    • Enable Row Level Security (RLS): 勾選此選項。RLS 是 Supabase 的核心安全特性,我們稍後會使用它來保護資料。
    • Columns: 新增以下欄位:
      • id (主鍵,uuid,預設值 gen_random_uuid()) - 保持預設。
      • task (類型 text) - 勾選「Not Null」。
      • is_complete (類型 boolean,預設值 false) - 勾選「Not Null」。
      • created_at (類型 timestamp with time zone,預設值 now()) - 保持預設。
    • 點擊「Save」。
  4. 設定 RLS 策略: 建立 todos 表後,點擊表名進入詳情頁,然後選擇「Policies」頁籤。

    • 點擊「New policy」->「Quickstart」。
    • 選擇「Enable read access to everyone」。
    • 點擊「Review」->「Create policy」。這將允許所有使用者讀取 todos 表中的資料。
    • 您可以重複此步驟,建立一個「Enable insert access for authenticated users only」的策略,允許登入使用者新增資料。

3. 使用 Supabase Client 進行資料操作 (前端範例)

Supabase 提供多種語言的 SDK,其中 JavaScript Client 是最常用的。我們將使用它來與您的 Supabase 專案互動。

  1. 取得專案 API 金鑰:

    • 在 Supabase 儀表板左側導覽列中,點擊「Project Settings」(齒輪圖示)。
    • 選擇「API」頁籤。
    • 您會找到 Project URLanon public (公開金鑰)。請記下這兩項資訊。
  2. 安裝 Supabase JS Client:
    bash
    npm install @supabase/supabase-js
    # 或者
    yarn add @supabase/supabase-js

  3. 初始化 Supabase Client:
    ```javascript
    import { createClient } from '@supabase/supabase-js';

    const supabaseUrl = 'YOUR_SUPABASE_PROJECT_URL'; // 替換為您的 Project URL
    const supabaseKey = 'YOUR_SUPABASE_ANON_PUBLIC_KEY'; // 替換為您的 anon public key
    const supabase = createClient(supabaseUrl, supabaseKey);
    ```

  4. 範例:新增資料 (Insert Data)
    ```javascript
    async function addTodo(task) {
    const { data, error } = await supabase
    .from('todos')
    .insert([{ task: task, is_complete: false }]);

    if (error) {
    console.error('Error adding todo:', error.message);
    } else {
    console.log('Todo added successfully:', data);
    }
    }

    // addTodo('學習 Supabase');
    ```

  5. 範例:查詢資料 (Fetch Data)
    ```javascript
    async function fetchTodos() {
    const { data: todos, error } = await supabase
    .from('todos')
    .select('*'); // 查詢所有欄位

    if (error) {
    console.error('Error fetching todos:', error.message);
    } else {
    console.log('Fetched todos:', todos);
    }
    return todos;
    }

    // fetchTodos();
    ```

  6. 範例:更新資料 (Update Data)
    ```javascript
    async function updateTodo(id, is_complete) {
    const { data, error } = await supabase
    .from('todos')
    .update({ is_complete: is_complete })
    .eq('id', id); // 根據 ID 進行更新

    if (error) {
    console.error('Error updating todo:', error.message);
    } else {
    console.log('Todo updated successfully:', data);
    }
    }

    // updateTodo('some-uuid-here', true); // 替換為實際的 todo ID
    ```

  7. 範例:刪除資料 (Delete Data)
    ```javascript
    async function deleteTodo(id) {
    const { data, error } = await supabase
    .from('todos')
    .delete()
    .eq('id', id);

    if (error) {
    console.error('Error deleting todo:', error.message);
    } else {
    console.log('Todo deleted successfully:', data);
    }
    }

    // deleteTodo('some-uuid-here'); // 替換為實際的 todo ID
    ```

  8. 範例:即時訂閱 (Realtime Subscription)
    ```javascript
    async function subscribeToTodos() {
    supabase
    .channel('public:todos') // 訂閱 'public' 模式下的 'todos' 表
    .on('postgres_changes', {
    event: '*', // 監聽所有事件 (INSERT, UPDATE, DELETE)
    schema: 'public',
    table: 'todos'
    }, payload => {
    console.log('Change received!', payload);
    // 根據 payload.eventType 處理不同的變更
    })
    .subscribe();

    console.log('Subscribed to todo changes.');
    }

    // subscribeToTodos();
    ```

4. 實作使用者認證 (Authentication)

Supabase 的認證功能非常強大且易於使用。

  1. 範例:註冊使用者 (Sign Up)
    ```javascript
    async function signUp(email, password) {
    const { data, error } = await supabase.auth.signUp({
    email: email,
    password: password,
    });

    if (error) {
    console.error('Error signing up:', error.message);
    } else {
    console.log('User signed up, check email for verification:', data);
    }
    }

    // signUp('[email protected]', 'password123');
    ```
    注意: 預設情況下,Supabase 會發送一封驗證郵件。您可以在「Authentication」->「Settings」中關閉「Email Confirm」來簡化測試流程。

  2. 範例:登入使用者 (Sign In)
    ```javascript
    async function signIn(email, password) {
    const { data, error } = await supabase.auth.signInWithPassword({
    email: email,
    password: password,
    });

    if (error) {
    console.error('Error signing in:', error.message);
    } else {
    console.log('User signed in:', data);
    // data.session 包含 session 資訊
    // data.user 包含使用者資訊
    }
    }

    // signIn('[email protected]', 'password123');
    ```

  3. 範例:登出使用者 (Sign Out)
    ```javascript
    async function signOut() {
    const { error } = await supabase.auth.signOut();

    if (error) {
    console.error('Error signing out:', error.message);
    } else {
    console.log('User signed out successfully.');
    }
    }

    // signOut();
    ```

進階應用與最佳實踐

1. 行級安全 (Row Level Security, RLS)

RLS 是 Supabase 安全的核心。透過 RLS 策略,您可以定義精確的規則,決定哪些使用者可以存取哪些資料列。例如,您可以設定一個策略,只允許使用者查看他們自己建立的待辦事項。

範例 RLS 策略 (允許使用者只查看自己的 todos):

CREATE POLICY "Users can view their own todos." ON public.todos
  FOR SELECT USING (auth.uid() = user_id);

-- 假設您的 todos 表有一個 user_id 欄位來關聯使用者

2. 資料庫函式與觸發器

您可以直接在 Supabase 的 PostgreSQL 資料庫中建立 SQL 函式和觸發器,以實現更複雜的後端邏輯。例如,在新增使用者時自動建立一個相關的資料庫記錄。

3. Supabase CLI

Supabase CLI 允許您在本地環境中開發和測試 Supabase 專案,然後將變更部署到遠端。這對於版本控制和團隊協作非常有用。

4. 性能考量

  • 索引 (Indexes): 對於經常查詢的欄位建立索引,可以顯著提高查詢性能。
  • 查詢優化: 撰寫高效的 SQL 查詢,避免全表掃描。
  • 分頁 (Pagination): 處理大量資料時,使用分頁來限制每次查詢返回的資料量。

總結

Supabase 作為一個開源的 BaaS 平台,為現代應用程式開發提供了一個強大且靈活的解決方案。它以 PostgreSQL 為核心,整合了資料庫、認證、儲存、即時和邊緣函式等一系列服務,讓開發者能夠以前所未有的速度構建全端應用程式。其開源的特性和對標準 SQL 的支援,也為開發者提供了更大的自由度和控制權。

透過本文的介紹和實作步驟,您應該已經對 Supabase 有了全面的了解,並能夠開始將其應用於您的專案中。無論您是開發個人專案、啟動新創公司,還是為現有應用程式尋找更高效的後端解決方案,Supabase 都值得您深入探索。

現在就動手嘗試吧!Supabase 將會是您加速開發旅程的強力夥伴。

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top