YAML vs JSON vs TOML:強み、使用例、YAMLの暗黙的型変換の落とし穴

各フォーマットが得意とする領域

各データシリアライゼーションフォーマットには得意な領域があります。JSON(JavaScript Object Notation、ECMA-404 および RFC 8259 として標準化)は HTTP API の共通言語です。ほぼすべての REST エンドポイントが使用し、すべての言語に依存関係なしの JSON パーサーがあり、文法は 1 ページに収まります。YAML(YAML Ain't Markup Language)は DevOps ツールの設定ファイルを支配しています——Kubernetes マニフェスト、GitHub Actions ワークフロー、Ansible プレイブック、Docker Compose ファイルはすべて YAML です。複数行文字列とコメントサポートにより、人間が毎日編集するファイルには JSON よりはるかに快適です。TOML(Tom's Obvious, Minimal Language)はプロジェクトレベルの設定に最適です。Rust パッケージの Cargo.toml、Python ビルドメタデータの pyproject.toml、Hugo サイト設定はすべて TOML を使用します。

これらのドメインの違いは偶然ではありません——各フォーマットの設計優先度を反映しています。JSON は相互運用性と決定性を優先し、YAML は人間の読みやすさと表現力を優先し、TOML は型安全性と予測可能な解析を優先します。

YAML の暗黙的型変換:ノルウェー問題

YAML で最も悪名高い落とし穴は、積極的な暗黙的型強制です。YAML 1.1(PyYAML < 6.0 や Ruby の Psych 4.0 以前を含む、最近まで多くのパーサーが使用していたバージョン)では、引用符なしのスカラーが型を決定するために一連の正規表現に対してテストされます。ブール値テストは yesnoonofftruefalse に大文字小文字を区別せずマッチします。これにより、ISO 3166-1 alpha-2 の国コードを使用するソフトウェアで実際のデータ整合性バグが発生しました。ノルウェーのコードは NO で、YAML 1.1 はこれをブール値 false に無音で変換します。norway: NO のようなマッピングは実行時に {norway: false} になります——エラーも警告もありません。

YAML 1.2(2009 年公開、ruamel.yaml と新しいパーサーで採用)はブール値セットを大文字小文字を区別する truefalse のみに絞り込み、yes/no/on/off バリアントを排除しました。しかし、何百万もの本番ファイルとそれを読むツールは依然として YAML 1.1 パーサーで動作しています。安全なルール:誤読される可能性のある文字列値は常に引用符で囲む——国コード、フラグのような単語、数値に見える文字列。

その他の YAML の落とし穴:タブ、アンカー、ドキュメントセパレータ

インデントは YAML の構文であり、タブは YAML のインデントとして絶対に有効ではありません。仕様はインデント位置でのタブ文字を明示的に禁止しています。しかしタブはほとんどのエディタでデフォルト不可視であり、意図しないタブは一部のパーサーで間違った行番号を示すスキャナーエラーを生成します。解決策は、エディタで「空白を表示」を有効にし、.yaml ファイルでタブをスペースに展開するよう設定することです。

YAML のアンカー&)とエイリアス*)はドキュメント全体でノードを再利用できます。これは繰り返されるコンテナ仕様を持つ長い Kubernetes マニフェストに非常に便利です。しかしエイリアス深度を制限しないパーサーへの「ビリオン・ラフス」スタイルの拡張攻撃も可能にします。ほとんどの本番パーサー(PyYAML 5.1+、SafeLoader の snakeyaml)はエイリアス深度を制限します。常に安全なロード API を使用してください。--- ドキュメントセパレータは 1 つのファイルに複数の YAML ドキュメントを許可します——kubectl apply -f はこれに依存——しかし一部のパーサーは明示的に反復しない限り最初のドキュメントのみを返し、残りを無音で破棄します。

TOML の明示的型と日時の優位性

TOML は構文レベルで各値に型を割り当て、暗黙的な強制変換はありません。整数は引用符なしで記述(port = 8080)、浮動小数点は小数点が必要(timeout = 1.5)、ブール値は小文字の truefalse、文字列は常に引用符が必要です。引用符なしの単語を生成する打ち間違いは解析エラーであり、無音の型変更ではありません。TOML 1.0(2021 年リリース)は 4 つの日時型をファーストクラスリテラルとして規定します:offset_date_time1979-05-27T07:32:00Z)、local_date_timelocal_datelocal_time

[table][[array of tables]] 構文は、ネストされたオブジェクトとオブジェクトの配列に明確にマッピングされます。[[servers]] ブロックの後に別の [[servers]] ブロックが続くと、servers 配列に 2 番目の要素が追加されます——明確で読みやすく、余分なスペースで壊れることはありません。トレードオフ:TOML はアンカーやマルチドキュメントファイルをサポートしません。

JSON の厳格さを機能として

JSON の文法には省略可能な機能、型強制、ドキュメントレベルの指令がありません。どのプラットフォームでも準拠したパーサーが {"active": true} を読むと、ブール値が生成されます——文字列 "true" でも整数 1 でもありません。この決定性により、JSON は人間に優しくないにもかかわらず API のデフォルト転送フォーマットになりました。RFC 8259 は仕様を強化します:JSON テキストはシリアライズされた値です。オブジェクト内の重複キーは明示的に「すべきでない」であり、エンコードは BOM なしの UTF-8 でなければなりません。

コメントがないことは JSON で最も引用される不満です。回避策:JSON5(コメントと末尾カンマを持つスーパーセット)、JSONC(VS Code の settings.json で使用)、解析前に // 行を取り除くなど。コメントが必要な設定の慣用的な解決策は、TOML や YAML を編集に使用し、JSON はビルドステップで生成されるマシン交換フォーマットとしてのみ使用することです。

適切なフォーマットの選択

実際の決定ルールはシンプルです:JSON はサービス境界を越えるあらゆるデータ(HTTP API、メッセージキュー、コードで生成された設定);YAML はオペレーターが手動で編集し、コメントや複数行文字列が必要な設定ファイル——特にそれを必須とするエコシステム(Kubernetes、GitHub Actions);TOML は強い型付けとフラットファイル構造が YAML の表現力より重要なプロジェクトレベルの設定。疑わしい場合は、エコシステムが既に使用しているフォーマットを優先してください。

大きな YAML 設定ファイルを引き継いで暗黙的型バグを疑う場合、素早い監査は YAML 1.2 リンター(yamllintspectral)で実行し、ブール値または数値パターンに一致する引用符なしの値を検索することです。新しいプロジェクトには、スキーマ(JSON Schema はツール経由で 3 つのフォーマットすべてに機能)の追加を検討してください。TeaFun の YAML / JSON / TOML コンバーターはインストールなしでブラウザで 3 つを切り替えられます。