iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0
Software Development

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

第十三關 - 支配者之手:Supabase Database API

  • 分享至 

  • xImage
  •  

Supabase API 示意圖

在前面的文章中,我們學會了如何使用 Supabase CLI 管理專案、建立資料表,以及各種開發工具。今天要介紹的是 Supabase 的核心功能之一:Database API 服務。這是讓你的前端應用與 Supabase 後端服務溝通的重要武器。

什麼是 Database API?

Database API 是一套自動生成的 RESTful API 服務,基於你的 PostgreSQL 資料庫結構自動建立。它提供了完整的 CRUD(Create、Read、Update、Delete)操作,並支援複雜的查詢、過濾、排序等功能。同時還包含身份驗證、即時訂閱、檔案儲存等 API 端點。

簡單來說

就像是 Supabase 幫你自動建立了一個「翻譯員」,讓你的網站前端可以用簡單的方式跟資料庫「對話」。不需要自己寫後端程式碼,Supabase 會根據你的資料表自動產生所有需要的 API。

就如君主的命令,使用「支配者之手」掌握絕對權力,透過 API 號令 Supabase 資料庫,操控你的數據軍團。

為什麼要使用 Supabase API?

傳統上,開發者需要:

  1. 自己寫後端 API 程式碼
  2. 處理資料庫連線和查詢
  3. 實作身份驗證邏輯
  4. 設定 API 路由和中介軟體
  5. 處理錯誤和安全性問題

這些工作既繁瑣又容易出錯。Database API 解決了這些痛點:

  • 自動生成:根據資料庫結構自動建立 API
  • 即時更新:資料表變更時 API 自動同步
  • 安全性內建:Row Level Security (RLS) 保護資料
  • 效能優化:內建快取和查詢優化
  • 開發友善:清晰的文件和 TypeScript 支援

如何使用 Database API

1. 建立 API 路由

Supabase 會根據你的資料庫結構自動生成 RESTful API 端點。每個資料表都會對應到一組 CRUD 操作的 API 路由。

範例:Todo List

首先需要建立一個 todos 資料表。

步驟 1:建立 todos 資料表

可以選擇以下兩種方式之一來建立資料表:

方式一:使用 SQL Editor

  1. 登入 Supabase Dashboard

  2. 進入 SQL Editor

    • 點擊左側選單的 SQL Editor
    • 點擊「+」 Create a new snippet
  3. 執行建表 SQL

-- 建立待辦事項資料表
CREATE TABLE todos (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  task TEXT NOT NULL,
  is_complete BOOLEAN DEFAULT false,
  user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 啟用 Row Level Security
ALTER TABLE todos ENABLE ROW LEVEL SECURITY;

方式二:使用 Dashboard 圖形介面

  1. 進入 Table Editor

    • 點擊左側選單的 Table Editor
    • 點擊 Create a new table
  2. 設定資料表

    • Table name: todos
    • Description: 待辦事項清單
    • 勾選 Enable Row Level Security (RLS)
  3. 新增欄位

    • id (uuid, primary key) - 系統自動建立
    • task (text, required) - 待辦事項內容
    • is_complete (boolean, default: false) - 是否完成
    • user_id (uuid, foreign key to auth.users) - 使用者 ID
    • created_at (timestamptz, default: now()) - 建立時間
  4. 點擊 Save 完成建立

步驟 2:設定 Row Level Security

可以在 Authentication 頁面 > Policies > 找到 todos 資料表,點擊 Create Policy

或在 SQL Editor 中執行以下 SQL:

-- 建立 RLS 政策
-- 允許使用者查看自己的待辦事項
CREATE POLICY "Users can view own todos" ON todos
  FOR SELECT USING (auth.uid() = user_id);

-- 允許使用者新增自己的待辦事項
CREATE POLICY "Users can insert own todos" ON todos
  FOR INSERT WITH CHECK (auth.uid() = user_id);

-- 允許使用者更新自己的待辦事項
CREATE POLICY "Users can update own todos" ON todos
  FOR UPDATE USING (auth.uid() = user_id);

-- 允許使用者刪除自己的待辦事項
CREATE POLICY "Users can delete own todos" ON todos
  FOR DELETE USING (auth.uid() = user_id);

步驟 3:查看自動生成的 API

Supabase 會自動生成這些 API 端點:

  1. 前往 API Doc頁面

    • 點擊左側選單的 API Doc
    • 查看自動生成的 API 文件
  2. 測試 API 端點

    • Tables and Views 區塊找到 todos
    • 點擊各種操作來查看範例程式碼
    • 可以直接在 Postman 中測試 API 呼叫
// 取得所有待辦事項
GET /rest/v1/todos

// 取得特定待辦事項
GET /rest/v1/todos?id=eq.123

// 建立新待辦事項
POST /rest/v1/todos

// 更新待辦事項
PATCH /rest/v1/todos?id=eq.123

// 刪除待辦事項
DELETE /rest/v1/todos?id=eq.123

步驟 4:在前端使用 API

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

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

// 取得使用者的所有待辦事項
const { data: todos, error } = await supabase
  .from('todos')
  .select('*')
  .order('created_at', { ascending: false })

// 新增待辦事項
const { data, error } = await supabase
  .from('todos')
  .insert([
    { 
      task: '學習 Supabase API',
      user_id: user.id
    }
  ])

// 標記為完成
const { data, error } = await supabase
  .from('todos')
  .update({ is_complete: true })
  .eq('id', todoId)

// 刪除待辦事項
const { data, error } = await supabase
  .from('todos')
  .delete()
  .eq('id', todoId)

客戶端函式庫參考文件

Supabase 提供了多種程式語言的官方客戶端函式庫,在不同的開發環境中使用 Supabase API:

  • JavaScript/TypeScript - 適用於 Web 應用和 Node.js
  • Python - 適用於 Python 應用程式
  • Dart/Flutter - 適用於 Flutter 行動應用
    ... 還有更多語言支援

完整的客戶端函式庫文件:
Supabase Client Libraries | Supabase Docs

每個客戶端函式庫都提供了:

  • 初始化 Supabase 客戶端
  • 完整的 CRUD 操作方法
  • 身份驗證功能
  • 即時訂閱支援
  • 檔案儲存 API
  • TypeScript 型別定義

使用官方 Todo 模板快速測試

快速體驗 Supabase API ,可以使用官方提供的 Todo List 模板。

  1. 複製官方模板
# 複製 Supabase 官方 Todo 範例
git clone https://github.com/supabase/supabase.git
cd supabase/examples/todo-list/nextjs-todo-list

# 安裝依賴
npm install
  1. 設定環境變數
# 複製環境變數範本
cp .env.local.example .env.local

編輯 .env.local 檔案:

NEXT_PUBLIC_SUPABASE_URL=your_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_SUPABASE_ANON_KEY
  1. 連接到遠端 Supabase 專案

    如果你還沒有 Supabase 專案,需要先建立一個:

    建立或選擇專案:

    連接本地專案並合併配置:

    # 連接到遠端專案
    SUPABASE_ENV=production npx supabase@latest link --project-ref <your-project-ref>
    

    同步配置:

    # 推送本地配置到遠端
    SUPABASE_ENV=production npx supabase@latest config push
    

    同步資料庫架構:

    # 推送本地資料庫架構到遠端
    SUPABASE_ENV=production npx supabase@latest db push
    
  2. 執行應用程式

npm run dev
  1. 開啟瀏覽器測試
    • 前往 http://localhost:3000
    • 你會看到一個完整的 Todo List 應用
    • 可以註冊、登入、新增、編輯、刪除待辦事項

與後端連線的設定

模板中已經包含了完整的連線設定:

// lib/supabase.js
import { createClient } from '@supabase/supabase-js'

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey)

2. API 金鑰

Supabase 提供兩種主要的 API 金鑰:

  • anon key:用於客戶端應用,有 Row Level Security 限制
  • service_role key:用於伺服器端,可繞過 RLS(需謹慎使用)

安全使用建議

前端使用(anon key):

// 安全:在前端使用 anon key
const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
)

後端使用(service_role key):

// 注意:只在伺服器端使用 service_role key
const supabaseAdmin = createClient(
  process.env.SUPABASE_URL,
  process.env.SUPABASE_SERVICE_ROLE_KEY
)

環境變數設定

# .env.local
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

小結

透過 Database API,前端開發者可以專注於使用者體驗,而不必擔心後端的複雜性。

... to be continued

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


上一篇
第十二關 - 何振宇的分身:Supabase Test
系列文
我獨自開發 - 用 Supabase 打造全端應用13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言