メインコンテンツへスキップ

← ブログ一覧へ

JSON と YAML の違いと、相互変換の方法

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 自体の性質であり、特定の変換器の問題ではありません。

機能の比較

機能JSONYAML
コメントなしあり(#)
末尾カンマ不可該当なし
人間の読みやすさ良い深い入れ子で有利
解析速度速い遅い
複数行文字列エスケープ \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 変換ツールは両者を相互変換し、その場で構文をチェックします——問題があれば正確な位置を示します。すべてブラウザ内で動作するため、機微な設定も端末から出ません。

関連ツール