YAML vs JSON: いつどちらのフォーマットを使うべきか
· 12分で読めます
目次
YAMLとJSONは、現代のソフトウェア開発における2つの主要なデータシリアライゼーションフォーマットです。どちらも同じデータ構造を表現できますが、哲学、構文、理想的な使用例において根本的に異なります。どちらのフォーマットを使うべきかを理解することは、プロジェクトの保守性、パフォーマンス、開発者体験に大きな影響を与える可能性があります。
この包括的なガイドでは、技術的な違い、実用的なアプリケーション、プロジェクトでYAMLとJSONのどちらを選択するかの意思決定基準について説明します。
概要
JSON(JavaScript Object Notation)は、2000年代初頭にDouglas CrockfordによってXMLの軽量な代替として作成されました。中括弧、角括弧、引用符を使用して、厳格で曖昧さのない構文を作成します。通常、任意のデータ構造を表現する方法は1つしかないため、JSONは非常に予測可能でマシンフレンドリーです。
YAML(YAML Ain't Markup Language)は、2001年頃に人間の可読性に焦点を当てて登場しました。中括弧の代わりにインデントを使用し、コメントをサポートし、同じデータを表現するための複数の構文アプローチを提供します。YAMLは技術的にはJSONのスーパーセットです。すべての有効なJSONドキュメントは有効なYAMLでもありますが、その逆は真ではありません。
クイックヒント: YAMLファイルを検証する必要がありますか?デプロイ前に構文エラーをキャッチするには、YAMLバリデーターを使用してください。
根本的な違いは、設計目標にあります。JSONはマシンパースと普遍的な互換性を優先し、YAMLは人間の可読性と表現力を優先します。この哲学的な分断は、構文の選択からエコシステムツールまで、すべてに影響を与えます。
構文の比較
同じデータ構造が両方のフォーマットでどのように見えるかを見てみましょう。これは典型的なサーバー設定です:
// JSON
{
"server": {
"host": "localhost",
"port": 8080,
"debug": true,
"ssl": {
"enabled": true,
"certificate": "/etc/ssl/cert.pem"
},
"origins": ["example.com", "api.example.com"],
"timeout": 30
}
}
# YAML同等
server:
host: localhost
port: 8080
debug: true
ssl:
enabled: true
certificate: /etc/ssl/cert.pem
origins:
- example.com
- api.example.com
timeout: 30
YAMLバージョンは、ほとんどの文字列の引用符を削除し、中括弧と角括弧を削除し、階層を示すためにインデントを使用します。結果として、文字数が約30%少なくなり、視覚的な明瞭性が大幅に向上します。
主な構文の違い
| 機能 | JSON | YAML |
|---|---|---|
| コメント | サポートされていません | #でサポート |
| 文字列の引用符 | 常に必要 | ほとんどの文字列でオプション |
| 複数行文字列 | エスケープシーケンスのみ | |と>でネイティブサポート |
| 末尾のカンマ | 許可されていません | 該当なし |
| アンカー/エイリアス | サポートされていません | &と*でサポート |
| データ型 | 文字列、数値、ブール値、null、配列、オブジェクト | 同じ + 日付、タイムスタンプ、バイナリ |
高度なYAML機能
YAMLには、JSON同等物がないいくつかの機能が含まれています:
# 複数行文字列
description: |
これは複数行の文字列です
改行を保持します。
ドキュメントに最適です。
# 折りたたまれた文字列(改行を削除)
summary: >
この長いテキストは
単一行に
折りたたまれ、単語間にスペースが入ります。
# アンカーとエイリアス(DRY原則)
defaults: &defaults
timeout: 30
retries: 3
production:
<<: *defaults
host: prod.example.com
staging:
<<: *defaults
host: staging.example.com
これらの機能により、YAMLは設定を文書化したり、複数のセクションで共通の値を再利用したりする必要がある設定ファイルに特に強力です。
JSONを使うべき場合
JSONは、マシン間通信、厳格な解析、普遍的な互換性が優先されるシナリオで優れています。
RESTおよびGraphQL API
JSONはWeb APIの事実上の標準です。すべてのプログラミング言語には成熟したJSON解析ライブラリがあり、フォーマットの厳格な構文はデータ交換における曖昧さを排除します。APIを構築または使用する場合、JSONはほぼ常に正しい選択です。
JSON.parse()とJSON.stringify()によるネイティブブラウザサポート- すべての実装で一貫した解析動作
- ネットワーク送信のための最小限のオーバーヘッド
- HTTPフレームワークとライブラリでの組み込みサポート
データベースストレージ
PostgreSQL、MongoDB、CouchDBなどの最新のデータベースには、特殊なインデックス作成とクエリ機能を備えたネイティブJSONデータ型があります。データをJSONとして保存すると、次のことが可能になります:
- マイグレーションなしのスキーマの柔軟性
- JSONパス式による効率的なクエリ
- アプリケーションオブジェクトとデータベースレコード間の直接マッピング
- オブジェクトリレーショナルマッピングにおけるインピーダンスミスマッチの削減
プロのヒント: データベースに保存したり、API経由で送信したりする前に、JSONフォーマッターを使用してJSONを美化および検証してください。
ライブラリの設定ファイル
他の開発者が統合するライブラリやツールを構築する場合、JSON設定ファイルは予測可能性を提供します。package.json、tsconfig.json、composer.jsonなどのファイルがJSONを使用する理由:
- プログラムによる変更が簡単
- 解析に曖昧さがないため、サポートの問題が少ない
- スキーマで簡単に生成および検証
- 自動化ツールとシームレスに連携
ブラウザベースのアプリケーション
クライアント側のJavaScriptアプリケーションの場合、JSONは自然な選択です。このフォーマットはJavaScript用に設計されており、ブラウザは追加のライブラリなしでネイティブに解析します。これにより、JSONは次の用途に理想的です:
- アプリケーション状態管理
- LocalStorageとSessionStorageのデータ
- 実行時にロードされる設定
- Webワーカーとのデータ交換
YAMLを使うべき場合
YAMLは、人間が主な編集者であり、可読性が解析速度よりも重要なシナリオで輝きます。
Infrastructure as Code
YAMLは、DevOpsエコシステム全体でインフラストラクチャ設定の標準となっています:
- Docker Compose: マルチコンテナアプリケーション定義
- Kubernetes: クラスタリソースマニフェスト
- Ansible: 自動化プレイブックとロール
- GitHub Actions: CI/CDワークフロー定義
- GitLab CI: パイプライン設定
これらのツールがYAMLを選択したのは、インフラストラクチャ設定は人間によって頻繁に編集され、コメントによる広範なドキュメントが必要であり、YAMLの視覚的なノイズを減らす能力から恩恵を受けるためです。
# Kubernetesデプロイメントの例
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
# リソース制限は暴走コンテナを防ぎます
resources:
limits:
memory: "256Mi"
cpu: "500m"
アプリケーション設定ファイル
開発者またはオペレーターが手動で編集するアプリケーション設定の場合、YAMLは優れた人間工学を提供します:
- コメントは設定が存在する理由とその有効範囲を説明します
- 複数行文字列はSQLクエリやテンプレートなどの複雑な値を処理します
- アンカーは環境間の重複を減らします
- よりクリーンな構文により、バージョン管理での差分がより読みやすくなります
ドキュメントとデータファイル
YAMLは、人間が読んで変更する必要がある構造化ドキュメント、テストフィクスチャ、データファイルに適しています:
- OpenAPI/Swagger仕様
- テストデータとフィクスチャ
- 国際化のための翻訳ファイル
- 静的サイトジェネレーターのコンテンツ(Jekyll、Hugo)
プロのヒント: フォーマット間で変換しますか?YAML to JSONコンバーターは、データ構造を保持しながら変換を処理します。
パフォーマンスに関する考慮事項
JSONとYAMLのパフォーマンスの違いは、特に大規模では重要になる可能性があります。
解析速度
JSONパーサーは、すべてのプログラミング言語でYAMLパーサーよりも一貫して高速です。厳格な構文により最適化された解析アルゴリズムが可能になり、多くの言語はインタープリタコードではなくネイティブコードでJSON解析を実装しています。
| 操作 | JSON | YAML | 差 |
|---|---|---|---|
| 1MBファイルの解析 | ~10ms | ~50-100ms | 5-10倍遅い |
| オブジェクトのシリアライズ | ~5ms | ~20-40ms | 4-8倍遅い |
| メモリオーバーヘッド | 低 | 中程度 | 約2倍 |
注: ベンチマークは実装とデータ構造の複雑さによって異なります。これらは典型的な使用例の概算値です。
パフォーマンスが重要な場合
次の場合はJSONを選択してください:
- 解析が頻繁に発生する(すべてのAPIリクエスト)
- 大きなデータファイル(>1MB)を扱う
- リソースに制約のある環境で実行する
- 起動時間が重要(サーバーレス関数)
次の場合、YAMLのパフォーマンスペナルティは無視できます:
- ファイルはアプリケーション起動時に一度だけ解析される
- 設定ファイルが小さい(<100KB)
- 人間の可読性が節約されるミリ秒よりも価値がある
ファイルサイズの比較
YAMLファイルは、構文オーバーヘッドの削減により、通常、同等のJSONよりも10〜30%小さくなります。ただし、この利点は圧縮により消えます。gzip圧縮されたJSONとYAMLファイルのサイズはほぼ同じです。
セキュリティへの影響
両方のフォーマットにはセキュリティ上の考慮事項がありますが、YAMLの柔軟性により追加の攻撃ベクトルが導入されます。
YAMLセキュリティリスク
YAMLの高度な機能は、信頼できない入力を解析する場合に悪用される可能性があります:
- 任意のコード実行: 一部のYAMLパーサーは、オブジェクトをインスタンス化したりコードを実行したりできるタグをサポートしています
- Billion laughs攻撃: 再帰的なアンカーは指数関数的なメモリ消費を引き起こす可能性があります
- 型の混乱: 暗黙的な型変換は予期しない動作につながる可能性があります
# コードを実行する可能性のある危険なYAML
!!python/object/apply:os.system
args: ['rm -rf /']
緩和戦略:
- 安全なロードモードを使用する(Pythonの
yaml.safe_load()) - カスタムタグとオブジェクトのインスタンス化を無効にする
- サンドボックス化せずに信頼できないソースからYAMLを解析しない
- 解析操作のリソース制限を実装する
JSONセキュリティの考慮事項
JSONは一般的により安全ですが、注意が必要です:
- プロトタイプ汚染: JavaScriptでは、悪意のあるJSONがオブジェクトプロトタイプを変更できます
- 数値精度: JavaScriptでは大きな整数が精度を失う可能性があります
- サービス拒否: 深くネストされた構造はスタックオーバーフローを引き起こす可能性があります
セキュリティのヒント: 処理する前に、常にスキーマに対して入力を検証してください。JSONにはJSON Schemaを、YAMLにはYamaleなどのツールを使用して検証してください。
ツールとエコシステム
ツールの成熟度と幅は、フォーマット間で大きく異なります。
JSONツール
JSONは、普遍的なサポートと成熟したツールから恩恵を受けています:
- 検証: JSON Schemaは、幅広い言語サポートで包括的な検証を提供します
- エディター: すべてのコードエディターには、構文の強調表示と検証を備えた組み込みのJSONサポートがあります
- コマンドラインツール: クエリ用の
jq