JSON 與 YAML 解決的是同一個問題 —— 把結構化資料表示成文字 —— 但它們做的取捨剛好相反。JSON 為機器無歧義的解析最佳化;YAML 為人類書寫最佳化。自 YAML 1.2 起,每一份合法的 JSON 文件也是合法的 YAML。本指南比較它們的語法、型別與特性,並說明何時該選哪一個。
簡短答案
程式之間交換的資料用 JSON —— API 回應、訊息 payload、任何由機器產生的東西。需要人手寫或編輯的檔案用 YAML —— CI pipeline、Kubernetes manifest、應用設定 —— 這些場景中註解與可讀性很重要。
並排語法對比
相同的資料用兩種格式各寫一次:
# YAML
service: api
replicas: 3
ports:
- 8080
- 8443
env:
LOG_LEVEL: info
DEBUG: false// JSON
{
"service": "api",
"replicas": 3,
"ports": [8080, 8443],
"env": {
"LOG_LEVEL": "info",
"DEBUG": false
}
}YAML 用縮排取代大括號與中括號,省掉了大多數引號,且允許註解。JSON 較囉嗦,但沒有有意義的空白,這讓它在解析與生成時都更容易做到可靠。
YAML 是 JSON 的超集合
自 YAML 1.2(2009)起,YAML 是 JSON 的嚴格超集合 —— 任何合法 JSON 文件都是合 法 YAML,因為 YAML 直接採用了 JSON 的「flow」語法。所以你把 JSON 貼到 YAML 檔案裡就能直接運作。背後的歷史見 YAML 1.2 與 JSON 相容性。
# 這是合法 YAML —— 同時也是合法 JSON
{"service": "api", "replicas": 3}特性比較
| 特性 | JSON | YAML |
|---|---|---|
| 註解 | 無 | 有(#) |
| 尾隨逗號 | 不允許 | 不適用(block 風格沒有逗號) |
| 多行字串 | 只能用轉義 \n | 原生支援(| 與 >) |
| Anchor / 參考 | 無 | 有(& / *) |
| 單檔多文件 | 不支援 | 支援(用 --- 分隔) |
| 有意義的空白 | 無 | 有(縮排有意義) |
| 解析複雜度 | 極簡 | 複雜 |
| 最適合 | 機器資料交換 | 人手編輯設定 |
型別處理:YAML 的尖刺
YAML 急於推斷型別,會出現 JSON 用強制引號就能避開的意外:
# 「Norway problem」—— 在 YAML 1.1 解析器裡這些會變布林
countries:
- NO # → false (!)
- SE
- true # → 布林,而非字串 "true"
version: 1.20 # → 數字 1.2,末尾的零丟掉了
zip: 01234 # → 668(在某些解析器裡被當成八進位) JSON 完全沒有這些歧義:"NO" 永遠是字串 NO,"01234" 永遠是那個字串。當 YAML 值必須是字串時,就明確加引號。
TOML 與 JSON5 的位置
另外兩種常見的「對人友善」設定格式經常出現在同一話題裡:
- TOML —— section/key 風格,專為人手編輯的應用設定設計(Cargo、Poetry、Hugo)。比 YAML 更嚴格、沒有有意義的縮排,原生型別化的值(datetime、整數、浮點、陣列、行內表)。資料大多是扁平表時最合適。
- JSON5 —— 給開發者用的寬鬆 JSON:允許註解、尾隨逗號、不加引號的 key、單引號、多行字串。不是 標準 JSON 解析器會接受的;你得用 JSON5 程式庫(或處理「註解 + 尾隨逗號」子集的 JSONC 解析器,例如
tsconfig.json)。
粗略定位:機器間交換用 JSON;深度巢狀、人手編輯的設定用 YAML;扁平的應用 / 工具設定用 TOML;想要「帶註解的 JSON」做編輯器設定又不想接受 YAML 的空白規則時,用 JSON5/JSONC。
什麼時候用哪一個
- 用 JSON:REST/GraphQL API、訊息佇列、瀏覽器
localStorage、package.json、任何由程式碼產生或消費的東西。 - 用 YAML:GitHub Actions / GitLab CI、Kubernetes 與 Docker Compose、Ansible playbook、需要人手編輯且要加註解的應用設定。
一個常見的模式:為了可讀性用 YAML 撰寫設定,然後在 build 或載入時轉成 JSON,讓應用程式本身只解析 JSON。
在 JSON 與 YAML 之間轉換
# Python —— YAML 轉 JSON
import yaml, json
data = yaml.safe_load(open('config.yaml'))
print(json.dumps(data, indent=2))
# 用 yq 在命令列
yq -o=json '.' config.yaml # YAML → JSON
yq -P '.' config.json # JSON → YAML或在 fixjson 的 YAML ⇄ JSON 轉換器 立刻於瀏覽器中轉換 —— 貼 YAML 拿到 JSON(或反過來),資料不會送到任何伺服器。
常見問題
YAML 比 JSON 好嗎?
沒有誰「比較好」—— 它們是為不同工作調校的。人手編輯的設定 YAML 較佳(註解、可讀性);機器間資料交換 JSON 較佳(簡單、快、解析無歧義)。
JSON 是合法 YAML 嗎?
是。自 YAML 1.2 起,YAML 是 JSON 的嚴格超集合,所以任何合法 JSON 文件都是合法 YAML。反之不成立 —— 大多數 YAML 不是合法 JSON。
為什麼 YAML 把「NO」變成 false?
YAML 會從未加引號的 scalar 推斷型別,有些解析器會把 NO、yes、on、off 讀成布林值(「Norway problem」)。給值加引號("NO")就能強制當字串。JSON 用強制引號完全避開這個問題。
設定檔該用 YAML 還是 JSON?
需要人手編輯、需要註解與多行字串就用 YAML;由工具產生或消費就用 JSON。很多團隊用 YAML 撰寫,並於載入時轉成 JSON。
在瀏覽器裡轉換與驗證
- YAML ⇄ JSON 轉換器 —— 任一方向皆可,完全在瀏覽器端
- YAML 格式化工具 —— 格式化、重新縮排、驗證 YAML
- 什麼是 JSON? —— YAML 是其超集合的那個格式
- 如何格式化 JSON —— 把轉換結果美化
- YAML 1.2 與 JSON 相容性 —— YAML 如何變成 JSON 超集合