JSON と YAML は、同じもの——オブジェクト・リスト・文字列・数値・真偽値からなる構造化データ——を書く 2 つの方法です。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"と書いていて、検証スクリプトが公開テキストとツールの実出力を比較して初めて食い違いを検出しました。小さな差ですが、自分のツールと一致しない解説ページは、そのページが無いより悪いです。
同じデータ、2 つのスタイル
JSON:
{ "name": "Yunknow", "tags": ["free", "fast"], "active": true }
YAML:
name: Yunknow
tags:
- free
- fast
active: true
同じデータの着替えです。YAML は記号を省いてインデントに頼ります。設定ファイルで好まれる理由がこれです。
入れ子は 2 つの記法の違いが最も目に見える部分です。この JSON —— リストと入れ子オブジェクト —— を私たちの JSON ↔ YAML 変換ツールに通すと:
list:
- 1
- 2
deep:
k: 'yes'
波括弧と角括弧が字下げになり、リスト項目が - になりました。データ自体は変わっていません。区切り記号が空白へ移っただけです。それが「YAML は読みやすい」と「YAML は壊しやすい」の両方の理由です。位置を誤った空白 1 つが構造の変更になります。
どちらを使うか
- JSON——API、
package.json、プログラムが自動で読み書きするもの。厳密で曖昧さがなく、広く対応。 - YAML——手で編集する設定:Docker Compose、Kubernetes、GitHub Actions、CI パイプライン。読みやすく、コメントも書けます。
よくある流れは、YAML で設定を書き、ツールがそれを JSON として読み込むことです。
この違いは、構文の好みよりずっと頻繁に選択を決めます。JSON の値型はちょうど 6 種類で型推論がないため、v: 'true' port: '8080' のようなことは起こり得ません。引用符付きの文字列は文字列のままで、救い出すべき規則もありません。YAML は推論します。それが手書き設定に心地よく、機械生成データに危険な理由です。
つまずきやすい落とし穴
- YAML のインデントは意味を持つ。 タブと空白の混在やインデントの誤りは、意味を変えたり解析を壊したりします。必ず空白でインデントを。
- JSON にするとコメントは消える。 JSON にはコメント構文がないため、YAML → JSON で
# メモ行は失われます。これは正常でバグではありません。 - 「ノルウェー問題」。 古い 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 のみ | ブロックスカラー |
| 1 ファイルに複数文書 | 不可 | 可(--- 区切り) |
見落とされがちな YAML の便利機能が、長文向けのブロックスカラーです。リテラルブロックは改行を保持し、折り畳みブロックは複数行を 1 行にまとめます:
description: |
1 行目はそのまま。
2 行目もそのまま。
summary: >
これは複数の
ソース行にまたがりますが
1 行になります。
よくある質問
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。