JSON 與 YAML 是寫同一件事的兩種方式:由物件、清單、字串、數字與布林值組成的結構化資料。JSON 用大括號與逗號包起來;YAML 用縮排與換行。因為兩者描述的結構完全相同,可以無損互轉——但有幾個坑值得先知道。
這件事我們自己測過 —— 而且在測的時候抓到自己的錯。 把
{"service":"api","ports":[80,443],"env":{"DEBUG":"false","RETRIES":3}}丟進我們的 JSON 轉 YAML 工具,回來是:service: api ports: - 80 - 443 env: DEBUG: 'false' RETRIES: 3
DEBUG的引號留著、RETRIES沒有,而這正是重點:在 YAML 裡沒加引號的false是布林值,拿掉引號型別會悄悄變掉。注意那是單引號。我們自己的實例頁一直寫成雙引號的"false",直到一支驗證腳本把發布的文字拿去跟工具真正的輸出比對才抓出來。差別很小,但一頁跟自己的工具對不上的說明文件,比沒有那一頁更糟。
一樣的資料,兩種風格
JSON:
{ "name": "Yunknow", "tags": ["free", "fast"], "active": true }
YAML:
name: Yunknow
tags:
- free
- fast
active: true
同樣的資料,只是換了件衣服。YAML 省掉標點、靠縮排,這正是設定檔愛用它的原因。
巢狀是這兩種寫法差別最看得見的地方。這段 JSON —— 一個清單加一個巢狀物件 —— 通過我們自己的 JSON ↔ YAML 轉換器:
list:
- 1
- 2
deep:
k: 'yes'
大括號與方括號變成了縮排,清單項目變成 -。資料本身完全沒變;分隔符搬到了空白裡。這同時就是「YAML 更好讀」和「YAML 更容易弄壞」的原因 —— 一個放錯位置的空白就是一次結構性的修改。
什麼時候用哪個
- JSON——API、
package.json、任何由程式自動讀寫的東西。嚴謹、無歧義、通用支援。 - YAML——你手動編輯的設定:Docker Compose、Kubernetes、GitHub Actions、CI 流程。好讀,還支援註解。
常見流程是:用 YAML 撰寫設定,再讓工具當成 JSON 讀取。
這個差別決定選擇的次數,遠比「語法喜好」多。JSON 只有六種值型別、沒有型別推論,所以 v: 'true' port: '8080' 這種事在 JSON 裡根本不可能發生:加了引號的字串就是字串,沒有任何規則需要把它救回來。YAML 會推論 —— 這正是它適合手寫設定檔、而對機器產生的資料有風險的原因。
常見的坑
- YAML 的縮排有意義。 混用 Tab 與空白、或縮排層級搞錯,會改變意思或直接解析失敗。請一律用空白縮排。
- 註解在轉成 JSON 時會消失。 JSON 沒有註解語法,所以 YAML → JSON 時
# 說明那幾行會不見。這是正常,不是 bug。 - 「挪威問題」。 舊版 YAML 中,未加引號的
no、yes、on、off會被當成布林值——所以國碼NO可能變成false。看起來像布林的字串要加引號。 - 錨點會被展開。 YAML 的
&anchor/*ref重用,在轉成 JSON 時會被攤平成一般資料。
而下面這個坑會花掉真實的時間。我們的轉換器把它變成「你沒要求的引號」顯示出來:
name: x
'on': true
'n': null
on 和 n 回來時被加了引號。在 YAML 1.1 裡,沒加引號的 on、off、y、n、yes、no 都是布林值,所以裸的鍵 on 會被解析成 true。反過來的情形是「值必須維持字串」:
v: 'true'
port: '8080'
兩個都保留了引號,因為拿掉引號會讓字串變成布林值、讓通訊埠號變成整數。這就是有名的「Norway problem」—— NO 被讀成 false —— 它是 YAML 本身的性質,不是某一個轉換器的問題。
特性對照
| 特性 | JSON | YAML |
|---|---|---|
| 註解 | 無 | 有(#) |
| 尾逗號 | 不允許 | 不適用 |
| 人類可讀性 | 好 | 深層巢狀更好讀 |
| 解析速度 | 較快 | 較慢 |
| 多行字串 | 只能跳脫 \n | 區塊純量 |
| 一檔多份文件 | 不支援 | 支援(--- 分隔) |
YAML 有個常被忽略的好用功能:區塊純量,適合長文字——字面區塊保留換行,折疊區塊則把多行併成一行:
description: |
第一行維持一行。
第二行維持一行。
summary: >
這段會跨越
好幾行原始碼
但最後變成一行。
小問答
YAML 是 JSON 的超集嗎? 實務上算是。從 YAML 1.2 起,任何合法的 JSON 都同時是合法的 YAML,所以 YAML 解析器能直接讀 JSON;反過來不行——JSON 讀不懂 YAML 的縮排語法。
API 該回傳哪個? 幾乎都選 JSON——解析快、無歧義、到處都支援。YAML 留給人類手動編輯的檔案。
轉換後我的註解跑去哪了? 被丟掉了,因為 JSON 沒有註解語法。若需要保留說明,可以改加一個真的鍵,例如 "_comment"。想更深入認識這個格式,看 JSON 是什麼。
在瀏覽器本機安全互轉
JSON ⇄ YAML 轉換工具能把兩者互轉,並邊轉邊檢查語法——有錯會指出確切位置。全程在你的瀏覽器本機執行,再私密的設定也不會離開你的裝置。
相關工具
- 要美化、壓縮或驗證 JSON,用 JSON 格式化工具。
- 要把表格式 JSON 匯進試算表,用 JSON ⇄ CSV ⇄ Excel。