使用 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 |
這些設定都是 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 |
搭配 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 Console 中,為
user表新增了一個 select 權限,給user角色。 - 修改
user表與order表之間的 relationship。 - 建立了一個新的 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」這個詞其實指的是兩種不同層級的變更紀錄機制:
- Database Migration:針對「資料庫結構」的異動,如新增表格、修改欄位、建立索引等
- Metadata Migration:針對「Hasura API 行為設定」的異動,如角色權限、表格關聯、remote schema 等
這兩者的資料來源不同、影響層級不同、儲存位置不同,但都可以透過 Hasura CLI 被版本化、追蹤與部署。
兩種 Migration 對照表
| 類型 | 資料位置 | 包含的內容 | 產出的檔案 | 常見格式 |
|---|---|---|---|---|
| Database Migration | PostgreSQL 資料庫 | 資料表(table)、欄位(column)、索引(index)、主鍵、外鍵、資料型別變更、constraint 等 | migrations/ | up.sql, down.sql, config.yaml |
| Metadata Migration | Hasura Metadata 層 | 權限(permissions)、relationships、remote schema、actions、event triggers 等 | metadata/ | YAML / JSON |
什麼情況會產生哪一種 Migration?
Hasura 會根據你在 Console 上「實際修改的內容」來自動決定產出哪一種 Migration:
| 你在 Console 的動作 | Migration 類型 |
|---|---|
| 新增 / 刪除一個資料表 | Database Migration |
| 在資料表上加欄位、改資料型別 | Database Migration |
| 建立一對多的 relationship | Metadata Migration |
調整 user 角色的權限(select 權限) | Metadata Migration |
| 加入一個 Remote Schema | Metadata Migration |
| 建立一個 Event Trigger | Metadata Migration |
有時候你一個操作會同時改動兩層(例如新增 table 時,同時設定 role 權限),那麼 Hasura CLI 會同時產生 兩種 Migration 檔案。
實務範例:新增一張 user 表,並設定權限
1. 使用 Hasura Console 建立 user 表,欄位為:
id: uuidname: textcreated_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 Migration | Metadata Migration |
|---|---|---|
| 操作對象 | PostgreSQL 資料庫 | Hasura 本身的 API 層設定 |
| 執行風險 | 高(可能導致資料損毀) | 較低(設定錯誤最多造成 API 錯誤) |
| 運行方式 | 執行 SQL 指令 | 套用設定檔(非 SQL) |
| 還原方式 | 需要正確撰寫 down.sql | Git 還原 metadata + apply |
| 適用操作 | 結構調整:新增欄位、改型別、加索引等 | 權限變更、建立 API 邏輯、設定關聯等 |
實務上如何管理這兩者?
✅ 建議作法:
- 每次操作 Hasura Console 時,都用 CLI 開啟(確保會產生 migration)
- 改完設定後,一定要
hasura metadata export - Git commit 時,一起 commit
migrations/與metadata/ - 部署到其他環境時:先 apply
migrations/,再 applymetadata/
常見會產生 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 給 GraphQL | 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 設定 | 避免設定被覆蓋或部署後遺失 |
哪些操作不需要 Migration?
| 行為 | 原因 |
|---|---|
| 新增一筆 user 資料(INSERT) | 屬於資料層,非設定層 |
| 刪除一筆 order 資料(DELETE) | 同上 |
| 修改某筆紀錄的名稱(UPDATE) | 屬於執行時資料操作,無需記錄設定 |
| 手動執行某個 mutation 呼叫 webhook | 屬於「使用 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 錯誤的問題。
整體開發與部署流程總結
- 使用
hasura console進行 metadata 設定(或使用 Cloud UI 並記得 export) - 操作後執行
hasura metadata export(確認更新) - 將
metadata/檔案加入 Git - 部署前用
hasura metadata diff比對環境差異 - 用
hasura metadata apply套用到遠端 - 必要時執行
hasura metadata reload確保生效
這整套流程聽起來繁瑣,但只要建立好習慣,很快你會發現 Hasura 的設定與部署其實比傳統後端更可控、更透明。
結語:Metadata Migration 是團隊協作的防撞牆
Hasura 的 Metadata 是建立你 GraphQL API 行為的根基。
Metadata Migration 則是保護這些設定在多人協作下不會「互相打架」、不會「環境不一致」的關鍵機制。
初學者最容易忽略這一層,等到 staging 和 production 行為不一樣才發現問題。
掌握好 Metadata Migration,不僅能提升開發效率,更能讓你團隊的部署更穩定、更可靠。