Kubernetesマニフェスト、GitHub Actionsワークフロー、docker-composeファイルを開いたことがあるなら、YAMLを使ったことがある。REST APIを呼び出したか、Node.jsプロジェクトの設定ファイルを書いたことがあるなら、JSONを使ったことがある。どちらもシリアライゼーションフォーマットだ。どちらも同じ種類のデータ構造 — マップ、配列、文字列、数値、ブール値、null — を記述する。ではなぜ2つあるのか?
短い答え:YAMLは人間にとって最適化し、JSONは機械にとって最適化する。 長い答えには、数十年の開発者経験、数回の委員会会議、そして驚くほど多くのエッジケースが含まれる。見ていこう。
JSONが得意なもの
JSON(JavaScript Object Notation)は2000年代初頭にAJAXリクエストのペイロードフォーマットとして普及した。意図的に小さかった — 6つの値型、コメントなし、トレーリングカンマなし、曖昧さなし。その厳格さがワイヤー上の強みだ:
- パーサーは小さく高速だ。
JSON.parseはすべてのブラウザとすべての言語ランタイムに同梱されている。考える必要はない。 - エラーは曖昧さがない。 JSONが壊れている場合、パーサーは正確にどの行と列かを伝える。
- 機械は意味を一致させる。 数値は数値、文字列は文字列、
trueはtrueだ。「yesはブール値か文字列か?」議論はない。
だからJSONがAPIの lingua franca(共通語)だ。2つのサービスが通信する際、最も驚きの少ないフォーマットが欲しい。
YAMLが得意なもの
YAML(YAML Ain’t Markup Language)は人間が書く設定ファイル用に設計された。JSONの厳格さの一部を読みやすさと交換した:
- 波括弧なし、角括弧なし。 構造はインデントだ。
docker-compose.ymlはリストのように上から下へ読める。 - コメント。
#でコメントが始まる。JSONにはコメント構文がない — コメントの欠如は、設定ファイルでJSONからYAMLに移行する最も一般的な理由だ。 - アンカーと参照。
&anchorと*referenceで値を1回定義し、再利用できる。JSONには同等のものがない;コピー&ペーストが必要だ。 - 複数行文字列。 リテラルブロック(
|)とフォールデッドブロック(>)が、エスケープいじりなしで文章とコードを処理する。
だからYAMLが人が手動で読む書きをする場所で支配的だ:Kubernetes、GitHub Actions、GitLab CI、Ansibleプレイブック、docker-compose、CloudFormation、OpenAPI仕様、そして2025年頃のAIエージェント設定ファイルの急増(.github/agents.yml、MCPサーバーマニフェスト、評価ハーネス)。
非対称性
汚い秘密を明かす:YAMLはJSONのデータモデルのスーパーセットだ。 有効なJSONファイルはすべてYAMLで表現できるが、逆は真ではない。YAMLにはJSONにない機能がある — コメント、アンカー、複数ドキュメントファイル、カスタムタグ。アンカーを使ったYAMLを書くと、損失なくJSONに変換できなくなる。アンカーは消える。
これはツールにとって重要だ。&defaults *defaultsを持つYAMLファイルがある場合、JSONに変換すると参照を展開(黙ってファイルを大きくする)か削除(黙ってファイルを小さくする)のいずれかになる。コメントも同様だ。JSONには置き場がない。
いつどちらを使うか
JSONを使う場合:
- ネットワーク経由でデータを送信する場合(API、メッセージキュー、イベントペイロード)。
- ファイルが人間ではなくコードによって読まれる場合。
- 厳格なパーサーからの曖昧さのないエラーメッセージが欲しい場合。
- 制約のあるデバイスでパース速度を最適化する場合。
YAMLを使う場合:
- 人間がファイルの主要な著者で読者である場合。
- 意意図を説明するコメントが欲しい場合。
- アンカーで設定のチャンクを再利用したい場合。
- ドメインのツールがそれを期待する場合(Kubernetes、CIなど)。
ほとんどのチームへの実用的な答え:ワイヤーにはJSON、設定にはYAML、データ交換には両方。 迷ったら、正規バージョンをJSON(損失なし)で保存し、開発者がテキストエディターを開くオーディエンスの場合のみ、コメントとアンカー付きのYAML(人間向け)を出力しよう。
変換時の一般的な落とし穴
- 数値とブール値はYAMLで自動型付けされる。
port: 8080は数値だ。port: "8080"は文字列だ。引用符を忘れるだけで型が変わることもある。 - アンカーとコメントはJSONで削除される。 どうしようもない — フォーマットには置き場がない。
- YAMLの
nullは曖昧だ。key:(空の値)はnull。key: nullもnull。key: ""は空の文字列。3つの異なるもの。 - タブはYAMLを壊す。 インデントはスペースでなければならない。タブはエラーだ。
- YAML 1.1 vs 1.2 vs 1.2.2。 YAML 1.1は
yes、no、on、offをブール値として扱った。YAML 1.2(js-yaml、PyYAML、2026年のほとんどのパーサーが使う仕様)はそうしない。2025年の1.2.2メンテナンスリリースは、ドキュメント終了マーカーとBOM処理のいくつかのエッジケースを修正した — ほとんどのパーサーは修正を黙って採用した。2018年頃のコードベースから移行している場合、設定はまだ微妙に壊れることがある。
役立つツール
両方を行き来する場合 — すべてのチームが両方を使うので、そうなる — 高速なクライアントサイドコンバーターが味方だ。DevSpeedToolsのYAML to JSONとJSON to YAMLはブラウザ内で完全に実行される。因此、シークレットを含む設定ファイルはマシンから出ない。DevTools → Networkを開けば、データを含むリクエストがないことがわかる。
時間が経ってごちゃごちゃになったYAMLには、YAMLフォーマッターがインデントを2スペースに正規化し、不一致な引用符を修正する。パースできないファイルには、YAMLバリデーターがすべてのエラーの正確な行と列を表示する。
結論:YAMLとJSONを競合フォーマットとして扱うのをやめよう。它们は補完的だ。正しいフォーマットは誰がファイルを読むかに依存する — 機械か、23時にデプロイがなぜ壊れたかをしようとする疲れた開発者か。