Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

本文為「Hasura Migration 完全指南」系列第 5 篇

Hasura Metadata Migration & 判斷流程:初學者完整指南

最後更新:2025年8月6日Web API

使用 Hasura 的過程中,你可能注意到:

有時候你沒有新增任何資料表,只是調整了一個角色的權限、修改了一個 relationship,卻突然在 metadata/ 資料夾中多了一堆 YAML 檔案。

這些,其實就是 Hasura 的 Metadata Migration。

很多剛接觸 Hasura 的初學者會疑惑:

「我只是調整一下設定,為什麼要做 Migration?」
「Metadata 到底是什麼?我什麼時候該管它?」

這篇文章將一步一步帶你理解:

  • 什麼是 Metadata Migration?
  • 和 Database Migration 有什麼不同?
  • 有哪些常見場景會觸發 Metadata 變動?
  • 實務上怎麼判斷「我到底要不要做 Migration?」

什麼是 Hasura 的 Metadata?

Hasura 其實不只是單純幫你轉接 GraphQL 和 PostgreSQL,它還維護了一層 「中介設定」,記錄你對 GraphQL API 的調整。

這層設定就叫做 Metadata,裡面包括:

設定類型舉例說明
權限設定(permissions)指定角色(如 user、admin)可以讀取哪些欄位
Relationships建立 Table 之間的關聯,如 one-to-many
Remote Schemas把外部 GraphQL 加進來當擴充 API
Actions自訂的 mutation 或 query(例如呼叫 webhook)
Event Triggers某表格的 insert/update/delete 發生後自動觸發事件
Function 設定使用 PostgreSQL function 並包裝成 GraphQL
舉例說明指定角色(如 user、admin)可以讀取哪些欄位
舉例說明建立 Table 之間的關聯,如 one-to-many
舉例說明把外部 GraphQL 加進來當擴充 API
舉例說明自訂的 mutation 或 query(例如呼叫 webhook)
舉例說明某表格的 insert/update/delete 發生後自動觸發事件
舉例說明使用 PostgreSQL function 並包裝成 GraphQL

這些設定都是 Hasura 自己儲存在 metadata 系統中,並不屬於你原本的 PostgreSQL schema。

Metadata Migration 是什麼?

在 Hasura 中,Metadata Migration 指的是:把你對 Hasura 設定的所有改動「具體地記錄下來」,並儲存成一組可重複執行的 YAML / JSON 檔案。

這個機制就像你在版本控制程式碼一樣,也能對 Hasura 的設定進行版本管理、變更追蹤與跨環境部署。

為什麼需要 Metadata Migration?

Hasura 除了管理資料表(Database)外,還有一層很重要的 GraphQL API 設定層,例如:

  • 某個角色能否看到某個欄位?
  • 這兩張表要不要建立關聯?
  • 某個 mutation 是不是觸發了一個 Webhook?
  • 有沒有整合外部 GraphQL schema?

這些行為設定就屬於 Hasura Metadata,而這些設定的變動如果不被紀錄,將導致:

  • ❶ 團隊成員之間設定不一致
  • ❷ 測試與正式環境的 API 行為不同
  • ❸ 上線後回不去,也無法追蹤改了什麼

為了解決這些問題,Hasura 提供了「Metadata Migration 機制」來把所有變動記錄下來。

Metadata Migration 能幫你做什麼?

當你使用 Hasura CLI 搭配 hasura metadata export,它會自動從 Hasura 伺服器抓取目前所有設定,並存成一組檔案(通常是 YAML 格式):

metadata/
├── actions.yaml
├── allow_list.yaml
├── cron_triggers.yaml
├── databases/
│   └── default/
│       ├── tables/
│       │   └── ...
│       ├── functions.yaml
│       ├── remote_relationships.yaml
│       └── ...
├── query_collections.yaml
└── version.yaml

這些檔案構成了「你目前的 Hasura 設定快照」。

Metadata Migration 的三大核心功能

功能說明
🔁 版本控制每次變更都能 commit 到 Git,用 Pull Request 審查
🤝 團隊協作不怕別人覆蓋你設定,大家都能保持一致
🚀 跨環境部署將 dev 上的設定 export,再 apply 到 staging / production
說明每次變更都能 commit 到 Git,用 Pull Request 審查
說明不怕別人覆蓋你設定,大家都能保持一致
說明將 dev 上的設定 export,再 apply 到 staging / production

搭配 Hasura CLI 的操作指令有哪些?

Hasura CLI 提供一整套針對 Metadata Migration 的工具,操作流程如下:

指令用途補充說明
hasura metadata export匯出當前 Hasura 設定為檔案通常在修改後執行一次,備份設定
hasura metadata apply將本地 metadata 套用到目標 Hasura用於部署、跨環境同步
hasura metadata diff比對本地與伺服器設定的差異可用來審查有哪些修改
hasura metadata reload強制讓 Hasura 重新載入 metadata偶爾操作後需 reload 才會生效
用途匯出當前 Hasura 設定為檔案
補充說明通常在修改後執行一次,備份設定
用途將本地 metadata 套用到目標 Hasura
補充說明用於部署、跨環境同步
用途比對本地與伺服器設定的差異
補充說明可用來審查有哪些修改
用途強制讓 Hasura 重新載入 metadata
補充說明偶爾操作後需 reload 才會生效

舉個例子更清楚

假設你今天做了以下操作:

  1. 在 Hasura Console 中,為 user 表新增了一個 select 權限,給 user 角色。
  2. 修改 user 表與 order 表之間的 relationship。
  3. 建立了一個新的 action:submitSurvey。

這些操作本身不會改動資料表結構,但它們會改變 GraphQL API 的行為。因此:

  • 這些設定就會被紀錄在 metadata/ 資料夾中
  • 你可以使用 Git commit 起來
  • 日後用 hasura metadata apply 部署到正式環境

也就是說,你的設定就像程式碼一樣,變得「可被追蹤」、「可被還原」、「可被部署」。

Metadata Migration 不是備份,是「基礎建設的一部分」

很多初學者會誤以為 metadata export 僅僅是一種備份,其實不是。

它是一種完整的設定描述檔,用來:

  • 建構 Hasura 行為邏輯
  • 同步多個環境一致性
  • 作為 CI/CD 自動部署設定的重要輸入

就像你在寫前端程式時會 commit components/,在 Hasura 開發時,也應該把 metadata/ 一併納入 Git 追蹤。

當然可以,以下是你指定段落 「三、Hasura 的兩種 Migration 對比」 的完整擴寫版本,除了表格對比外,也補充了概念背景、實務差異、舉例說明、同步策略與初學者常犯的誤解,讓這段教學更完整:

Hasura 的兩種 Migration 對比

在 Hasura 中,「Migration」這個詞其實指的是兩種不同層級的變更紀錄機制:

  1. Database Migration:針對「資料庫結構」的異動,如新增表格、修改欄位、建立索引等
  2. Metadata Migration:針對「Hasura API 行為設定」的異動,如角色權限、表格關聯、remote schema 等

這兩者的資料來源不同、影響層級不同、儲存位置不同,但都可以透過 Hasura CLI 被版本化、追蹤與部署。

兩種 Migration 對照表

類型資料位置包含的內容產出的檔案常見格式
Database MigrationPostgreSQL 資料庫資料表(table)、欄位(column)、索引(index)、主鍵、外鍵、資料型別變更、constraint 等migrations/up.sql, down.sql, config.yaml
Metadata MigrationHasura Metadata 層權限(permissions)、relationships、remote schema、actions、event triggers 等metadata/YAML / JSON
資料位置PostgreSQL 資料庫
包含的內容資料表(table)、欄位(column)、索引(index)、主鍵、外鍵、資料型別變更、constraint 等
產出的檔案migrations/
常見格式up.sql, down.sql, config.yaml
資料位置Hasura Metadata 層
包含的內容權限(permissions)、relationships、remote schema、actions、event triggers 等
產出的檔案metadata/
常見格式YAML / JSON

什麼情況會產生哪一種 Migration?

Hasura 會根據你在 Console 上「實際修改的內容」來自動決定產出哪一種 Migration:

你在 Console 的動作Migration 類型
新增 / 刪除一個資料表Database Migration
在資料表上加欄位、改資料型別Database Migration
建立一對多的 relationshipMetadata Migration
調整 user 角色的權限(select 權限)Metadata Migration
加入一個 Remote SchemaMetadata Migration
建立一個 Event TriggerMetadata Migration
Migration 類型Database Migration
Migration 類型Database Migration
Migration 類型Metadata Migration
Migration 類型Metadata Migration
Migration 類型Metadata Migration
Migration 類型Metadata Migration

有時候你一個操作會同時改動兩層(例如新增 table 時,同時設定 role 權限),那麼 Hasura CLI 會同時產生 兩種 Migration 檔案。

實務範例:新增一張 user 表,並設定權限

1. 使用 Hasura Console 建立 user 表,欄位為:

  • id: uuid
  • name: text
  • created_at: timestamptz

2. 為角色 user 加上 select 權限,允許讀取 name 欄位

這時,Hasura CLI 會自動產生:

  • migrations/20240805120000_create_user_table/
    包含 up.sql, down.sql → 對應表格建立
  • metadata/tables.yaml, metadata/permissions.yaml
    更新了角色權限設定

這種情況下就會同時產生 Database + Metadata Migration。

Hasura 如何知道要產出哪種 Migration?

Hasura CLI 的行為是這樣設計的:

  • 你在 CLI 開啟的 Console 中進行操作(hasura console 指令開的頁面)
  • 且 勾選左下角的 This is a migration(預設會打勾)
  • 那麼 Hasura 會針對你每次在 Console 上的異動,自動產生:
  • up.sql / down.sql(若為資料庫異動)
  • metadata/ YAML(若為 Hasura 設定異動)

✅ 補充提醒:

這個行為只有在你用 CLI 開啟 Console 時才會生效。

如果你使用雲端版的 Hasura Console(cloud.hasura.io),就不會自動產生 migration 檔案。

延伸說明:兩種 Migration 為何要區分?

Hasura 之所以把兩種 Migration 分開,是因為它們的「變動性質」與「部署方式」不同:

對比項目Database MigrationMetadata Migration
操作對象PostgreSQL 資料庫Hasura 本身的 API 層設定
執行風險高(可能導致資料損毀)較低(設定錯誤最多造成 API 錯誤)
運行方式執行 SQL 指令套用設定檔(非 SQL)
還原方式需要正確撰寫 down.sqlGit 還原 metadata + apply
適用操作結構調整:新增欄位、改型別、加索引等權限變更、建立 API 邏輯、設定關聯等
Database MigrationPostgreSQL 資料庫
Metadata MigrationHasura 本身的 API 層設定
Database Migration高(可能導致資料損毀)
Metadata Migration較低(設定錯誤最多造成 API 錯誤)
Database Migration執行 SQL 指令
Metadata Migration套用設定檔(非 SQL)
Database Migration需要正確撰寫 down.sql
Metadata MigrationGit 還原 metadata + apply
Database Migration結構調整:新增欄位、改型別、加索引等
Metadata Migration權限變更、建立 API 邏輯、設定關聯等

實務上如何管理這兩者?

✅ 建議作法:

  • 每次操作 Hasura Console 時,都用 CLI 開啟(確保會產生 migration)
  • 改完設定後,一定要 hasura metadata export
  • Git commit 時,一起 commit migrations/ 與 metadata/
  • 部署到其他環境時:先 apply migrations/,再 apply metadata/

常見會產生 Metadata Migration 的情境

Hasura 中的 Metadata 是用來記錄你「對 GraphQL API 行為的設定」。

這些設定雖然不會改動 PostgreSQL 資料表本身,但卻會影響使用者能不能存取某張表、能不能看到某個欄位、API 能不能呼叫某個 webhook 等等。

以下操作都會產生 metadata:

操作行為對應的 Metadata 設定檔案
✅ 修改角色權限(insert/select/update/delete)permissions.yaml(位於 metadata/tables/ 中)
✅ 建立或刪除 Table 關聯(object / array)tables.yaml(也位於 metadata/tables/ 中)
✅ 加入 Remote Schema(例如整合其他 GraphQL API)remote_schemas.yaml
✅ 建立自定義 Action(例如 submitSurvey)actions.yaml、action_permissions.yaml
✅ 新增 Event Trigger(如 on_order_created)event_triggers.yaml
✅ 修改 Function 是否 expose 給 GraphQLfunctions.yaml
對應的 Metadata 設定檔案permissions.yaml(位於 metadata/tables/ 中)
對應的 Metadata 設定檔案tables.yaml(也位於 metadata/tables/ 中)
對應的 Metadata 設定檔案remote_schemas.yaml
對應的 Metadata 設定檔案actions.yaml、action_permissions.yaml
對應的 Metadata 設定檔案event_triggers.yaml
對應的 Metadata 設定檔案functions.yaml

實務例子說明

✅ 修改權限(最常見)

在 Hasura Console 中,當你給 user 角色新增 select 權限時,其實背後會被轉換成類似這樣的設定:

select_permissions:
  - role: user
    permission:
      columns:
        - id
        - name
      filter: {}

這些設定會寫進 metadata/tables/<your-table>.yaml 裡,屬於 metadata 的一部分。

✅ 建立 Relationship

當你把 order.user_id 和 user.id 建立關聯(one-to-many)時,Hasura 會記錄這段關係,寫入 object_relationships 欄位:

object_relationships:
  - name: user
    using:
      foreign_key_constraint_on: user_id

這也會產生 metadata 變動。

✅ 加入 Remote Schema

例如你想整合 Stripe 或自建 GraphQL API,只要輸入 URL 並點「Add Remote Schema」,Hasura 就會把設定寫入:

remote_schemas:
  - name: Stripe
    definition:
      url: https://api.stripe.com/graphql

這屬於 metadata 設定,也必須用 metadata export 匯出。

📌 提醒:即使只是「刪除一個權限」或「改了一個 relationship 名稱」,也會改變 metadata,而這類改動如果沒記錄下來,就無法部署到其他環境,也無法追蹤誰改了什麼。

實務判斷流程:什麼情況要做 Metadata Migration?

Hasura 的 Migration 系統分為 Database(資料庫結構)與 Metadata(API 設定)兩種,因此你每次在 Hasura 上操作時,都需要先判斷:這次的改動到底是哪一類?

快速判斷流程圖

我現在做的事情是什麼?
│
├─► 改動資料表結構?(加欄位、建索引) 
│       → ✅ 建立 Database Migration(migrations/)
│
├─► 改的是 Hasura 設定?(改權限、建 relationship) 
│       → ✅ 建立 Metadata Migration(metadata/)
│
└─► 只是塞資料?(INSERT / UPDATE / DELETE) 
        → ❌ 不需要 Migration(屬於 runtime 資料)

建議做 Metadata Migration 的具體情境

以下這些改動,都是 Hasura 內部 GraphQL 行為的設定,一定要產生 metadata 並加入版本控制:

情境為什麼需要 Metadata Migration?
✅ 為 user 角色新增 select 權限會改變 GraphQL API 是否能查詢這張表
✅ 移除 admin 角色的 delete 權限沒記錄下來的話,部署後行為會不一致
✅ 新增 order 表的 object relationship影響 order { user { ... } } 是否能查
✅ 設定 Remote Schema會改變 API 能不能 query 外部資料源
✅ 團隊多位工程師同時開發 Hasura 設定避免設定被覆蓋或部署後遺失
為什麼需要 Metadata Migration?會改變 GraphQL API 是否能查詢這張表
為什麼需要 Metadata Migration?沒記錄下來的話,部署後行為會不一致
為什麼需要 Metadata Migration?影響 order { user { ... } } 是否能查
為什麼需要 Metadata Migration?會改變 API 能不能 query 外部資料源
為什麼需要 Metadata Migration?避免設定被覆蓋或部署後遺失

哪些操作不需要 Migration?

行為原因
新增一筆 user 資料(INSERT)屬於資料層,非設定層
刪除一筆 order 資料(DELETE)同上
修改某筆紀錄的名稱(UPDATE)屬於執行時資料操作,無需記錄設定
手動執行某個 mutation 呼叫 webhook屬於「使用 API」,不屬於「建 API」
原因屬於資料層,非設定層
原因同上
原因屬於執行時資料操作,無需記錄設定
原因屬於「使用 API」,不屬於「建 API」

關鍵觀念總結

Metadata Migration 是「設定行為的紀錄」;Database Migration 是「結構變更的紀錄」;資料操作則不需要 Migration。

如果你是多人團隊開發 Hasura,建議每次設定完畢都執行:

hasura metadata export
git add metadata/
git commit -m "feat: 新增 user 角色的權限設定"

這樣才能確保後續部署、測試、審查都不會出錯。

明白了,下面是我針對你原本提供的內容和意圖,重新撰寫成更自然流暢、具文章感的版本的「六、Metadata Migration 怎麼做?」章節。它會保留完整的知識量與技術細節,但語氣會更像是閱讀一篇教學文章,而不是逐條說明的手冊:

Metadata Migration 怎麼做?

在 Hasura 中,除了記錄資料庫結構變化的 Database Migration,還有一個經常被初學者忽略,卻同樣重要的機制:Metadata Migration。

它負責追蹤所有與 Hasura API 設定有關的變動,例如角色權限、資料表關聯、remote schemas、自定義 actions 等,這些都不是寫入 PostgreSQL,而是存在 Hasura 自己的 metadata 層。

那麼問題來了:這些設定要怎麼被版本控制?又該如何部署到 staging 或 production 環境?這就是 Metadata Migration 的作用。

不是所有操作都會自動記錄:關於 hasura metadata export

許多使用者會有一個直覺:「我透過 Hasura Console 操作了權限或關聯,設定應該已經自動儲存到本地 metadata/ 了吧?」

但實際上,這取決於你是透過哪種方式開啟 Console。

  • 如果你是使用 hasura console(CLI 開的 Console),那麼好消息是:Hasura CLI 會在你操作 metadata 的同時,自動將設定寫入你本地的 metadata/ 資料夾,不需要額外匯出。
  • 但如果你是透過 cloud.hasura.io 的雲端 Console,或手動輸入網址打開 Hasura UI,那麼這些變動只會寫入伺服器,不會更新你本地的檔案。這時你就需要手動執行:
hasura metadata export

這個指令會從 Hasura Server 匯出當前的設定狀態,並寫入本地專案的 metadata/ 資料夾中,方便你進行版本控制與部署。

即使你是用 CLI 開的 Console,我也建議在 commit 前養成習慣性執行一次 export,確保所有設定都有被寫入,避免被 CLI 寫入失敗卻沒察覺。

把 metadata 加進 Git,是團隊協作的關鍵

Hasura 的 metadata 設定會以 YAML(或 JSON)格式儲存在 metadata/ 資料夾中,這些檔案可以被版本控制,讓團隊成員可以追蹤設定改動、發 PR 審查,並且保證 staging 與 production 環境的設定保持一致。

當你完成設定變更並確認 metadata 檔案正確後,記得:

git add metadata/
git commit -m "feat: 新增 user 角色的權限與 table 關聯設定"

這是整合 Hasura 到多人協作流程中最關鍵的一步。

部署:將 metadata 套用到其他環境

當你在本地測試無誤後,接下來就是部署 metadata 到 staging 或 production。只需要一行指令,就可以將你本地的設定套用到指定的 Hasura 伺服器:

hasura metadata apply \
  --endpoint https://staging.example.com \
  --admin-secret your-secret

這個動作會將 metadata/ 裡的所有檔案同步上去,直接影響 GraphQL API 的權限、關聯與行為。

請注意:這會完整覆蓋遠端伺服器上的 metadata 設定,因此建議部署前先比對差異,避免誤蓋掉其他人的改動。

如何部署前比對差異:hasura metadata diff

在實務上,我們通常會在 apply 之前加上一個檢查步驟,使用:

hasura metadata diff \
  --endpoint https://staging.example.com \
  --admin-secret your-secret

這會顯示你本地設定與 staging 伺服器上的設定差異,像是某個欄位的權限不一致、某個關聯未同步,這樣能有效避免「部署後才發現破壞了某些功能」的情況。

這個指令也非常適合在 PR Review 階段做為審查工具,讓 reviewer 清楚看到 metadata 改動的具體內容。

reload:當 apply 後設定沒生效怎麼辦?

偶爾你可能會遇到一種情況:你已經套用 metadata,但 Console 上的 API 行為卻沒有變化。這時候,很可能是 Hasura Server 的 metadata 沒有自動 reload。

別擔心,Hasura 提供一個指令可以強制重新載入 metadata:

hasura metadata reload \
  --endpoint https://your-env.com \
  --admin-secret your-secret

這可以幫助你解決 API 行為沒同步、或發生 metadata inconsistent 錯誤的問題。

整體開發與部署流程總結

  1. 使用 hasura console 進行 metadata 設定(或使用 Cloud UI 並記得 export)
  2. 操作後執行 hasura metadata export(確認更新)
  3. 將 metadata/ 檔案加入 Git
  4. 部署前用 hasura metadata diff 比對環境差異
  5. 用 hasura metadata apply 套用到遠端
  6. 必要時執行 hasura metadata reload 確保生效

這整套流程聽起來繁瑣,但只要建立好習慣,很快你會發現 Hasura 的設定與部署其實比傳統後端更可控、更透明。

結語:Metadata Migration 是團隊協作的防撞牆

Hasura 的 Metadata 是建立你 GraphQL API 行為的根基。

Metadata Migration 則是保護這些設定在多人協作下不會「互相打架」、不會「環境不一致」的關鍵機制。

初學者最容易忽略這一層,等到 staging 和 production 行為不一樣才發現問題。

掌握好 Metadata Migration,不僅能提升開發效率,更能讓你團隊的部署更穩定、更可靠。

上一篇Hasura Database Migration:從 0 到 1 的基礎操作
下一篇Hasura Migration 檔案長什麼樣?up/down.sql & yaml 解剖
目前還沒有留言,成為第一個留言的人吧!

發表留言

留言將在審核後顯示。

Web API

目錄

  • 什麼是 Hasura 的 Metadata?
  • Metadata Migration 是什麼?
  • 為什麼需要 Metadata Migration?
  • Metadata Migration 能幫你做什麼?
  • Metadata Migration 的三大核心功能
  • 搭配 Hasura CLI 的操作指令有哪些?
  • 舉個例子更清楚
  • Metadata Migration 不是備份,是「基礎建設的一部分」
  • Hasura 的兩種 Migration 對比
  • 兩種 Migration 對照表
  • 什麼情況會產生哪一種 Migration?
  • 實務範例:新增一張 user 表,並設定權限
  • Hasura 如何知道要產出哪種 Migration?
  • 延伸說明:兩種 Migration 為何要區分?
  • 實務上如何管理這兩者?
  • 常見會產生 Metadata Migration 的情境
  • 以下操作都會產生 metadata:
  • 實務例子說明
  • 實務判斷流程:什麼情況要做 Metadata Migration?
  • 快速判斷流程圖
  • 建議做 Metadata Migration 的具體情境
  • 哪些操作不需要 Migration?
  • 關鍵觀念總結
  • Metadata Migration 怎麼做?
  • 不是所有操作都會自動記錄:關於 hasura metadata export
  • 把 metadata 加進 Git,是團隊協作的關鍵
  • 部署:將 metadata 套用到其他環境
  • 如何部署前比對差異:hasura metadata diff
  • reload:當 apply 後設定沒生效怎麼辦?
  • 整體開發與部署流程總結
  • 結語:Metadata Migration 是團隊協作的防撞牆