YAMLからJSONへの変換は、開発者が日常的に直面する最も一般的なデータ形式タスクの一つです。Kubernetesマニフェスト、Docker Composeファイル、CI/CDパイプラインの管理において、YAMLとJSON間の変換は頻繁に必要になります。この包括的なガイドでは、変換ツール、パースプロセス、コード例、ベストプラクティスを解説します。
無料オンラインYAML to JSON / JSON to YAML変換ツールをお試しください。
YAMLとは?
YAML(YAML Ain't Markup Language)は、設定ファイルやデータ交換に広く使用される人間に優しいデータシリアライゼーション言語です。YAMLパーサーはインデントベースの構造を読み取り、ネイティブデータ構造に変換します。
YAMLは空白インデント(タブは禁止)で構造を表現します。スカラー型、シーケンス(配列)、マッピング(辞書)をサポートし、アンカーとエイリアス、複数行文字列、---で区切られた複数ドキュメントなどの高度な機能を備えています。YAML構文はJSONのスーパーセットです。
YAMLはKubernetes、Ansible、Docker Compose、GitHub Actions、OpenAPIなど多くのクラウドネイティブツールの推奨形式です。
YAML vs JSON:主な違い
YAMLとJSONの違いを理解することで、適切な形式を選択できます:
| 特徴 | YAML | JSON |
|---|---|---|
| 構文 | インデントベース | ブラケット・ブレース区切り |
| コメント | #でサポート | 非サポート |
| データ型 | 文字列、整数、浮動小数、ブール、null、日付 | 文字列、数値、ブール、null、配列、オブジェクト |
| 可読性 | 非常に読みやすい | より冗長 |
| 速度 | 遅い | 速い |
YAMLからJSON変換の仕組み
YAML to JSONコンバーターは、多段階のパースとシリアライゼーションプロセスを実行します。
ステップ1:字句解析 — YAMLパーサーがトークンを識別します。
ステップ2:AST構築 — トークンが階層構造を表す抽象構文木に組み立てられます。
ステップ3:ネイティブデータ構造 — ASTが型解決付きでネイティブ構造に変換されます。
ステップ4:JSONシリアライゼーション — 構造がJSONとしてシリアライズされます。YAMLコメントは破棄されます。
YAML to JSON コード例
JavaScript / Node.js (js-yaml)
js-yamlはJavaScript用の最も人気のあるYAMLパーサーです:
// ===== YAML to JSON (Node.js) =====
const yaml = require('js-yaml');
const fs = require('fs');
// Parse YAML string to JavaScript object
const yamlString = `
server:
host: localhost
port: 8080
ssl: true
database:
name: myapp
replicas:
- host: db1.example.com
port: 5432
- host: db2.example.com
port: 5432
# Connection pool settings
pool:
min: 5
max: 20
`;
const data = yaml.load(yamlString);
const json = JSON.stringify(data, null, 2);
console.log(json);
// {
// "server": {
// "host": "localhost",
// "port": 8080,
// "ssl": true
// },
// "database": {
// "name": "myapp",
// "replicas": [
// { "host": "db1.example.com", "port": 5432 },
// { "host": "db2.example.com", "port": 5432 }
// ],
// "pool": { "min": 5, "max": 20 }
// }
// }
// ===== JSON to YAML =====
const jsonData = { name: 'app', version: '2.0', features: ['auth', 'logging'] };
const yamlOutput = yaml.dump(jsonData, { indent: 2 });
console.log(yamlOutput);
// name: app
// version: '2.0'
// features:
// - auth
// - logging
// ===== Read YAML file and convert to JSON =====
const fileContent = fs.readFileSync('config.yaml', 'utf8');
const config = yaml.load(fileContent);
fs.writeFileSync('config.json', JSON.stringify(config, null, 2));
// ===== Handle multi-document YAML =====
const multiDoc = `
---
name: doc1
---
name: doc2
`;
const docs = yaml.loadAll(multiDoc);
console.log(JSON.stringify(docs, null, 2));
// [{ "name": "doc1" }, { "name": "doc2" }]Python (PyYAML)
任意コード実行を防ぐため、常にyaml.safe_load()を使用してください:
import yaml
import json
# ===== YAML to JSON =====
yaml_string = """
server:
host: localhost
port: 8080
ssl: true
database:
name: myapp
replicas:
- host: db1.example.com
port: 5432
- host: db2.example.com
port: 5432
pool:
min: 5
max: 20
"""
# Always use safe_load (prevents arbitrary code execution)
data = yaml.safe_load(yaml_string)
json_output = json.dumps(data, indent=2, ensure_ascii=False)
print(json_output)
# ===== JSON to YAML =====
json_string = '{"name": "app", "version": "2.0", "features": ["auth", "logging"]}'
json_data = json.loads(json_string)
yaml_output = yaml.dump(json_data, default_flow_style=False, allow_unicode=True)
print(yaml_output)
# ===== File conversion =====
# YAML file to JSON file
with open('config.yaml', 'r') as yf:
config = yaml.safe_load(yf)
with open('config.json', 'w') as jf:
json.dump(config, jf, indent=2)
# JSON file to YAML file
with open('data.json', 'r') as jf:
data = json.load(jf)
with open('data.yaml', 'w') as yf:
yaml.dump(data, yf, default_flow_style=False)
# ===== Handle multi-document YAML =====
multi_yaml = """
---
name: doc1
type: config
---
name: doc2
type: data
"""
docs = list(yaml.safe_load_all(multi_yaml))
print(json.dumps(docs, indent=2))
# ===== Preserve key order (Python 3.7+) =====
# dict maintains insertion order by default
ordered = yaml.safe_load(yaml_string)
print(json.dumps(ordered, indent=2)) # keys stay in YAML orderBash / CLI (yq)
コマンドライン変換ではyqが最も効率的です:
# ===== yq: YAML processor (like jq for YAML) =====
# Convert YAML file to JSON
yq -o=json config.yaml
# Convert YAML to JSON and save to file
yq -o=json config.yaml > config.json
# Convert JSON to YAML
yq -P config.json
# Convert JSON to YAML and save
yq -P config.json > config.yaml
# Extract a specific field from YAML as JSON
yq -o=json '.server.port' config.yaml
# ===== Python one-liner =====
# YAML to JSON (stdin)
cat config.yaml | python3 -c \
'import sys,yaml,json; json.dump(yaml.safe_load(sys.stdin),sys.stdout,indent=2)'
# YAML to JSON (file)
python3 -c \
'import yaml,json; print(json.dumps(yaml.safe_load(open("config.yaml")),indent=2))'
# JSON to YAML
cat data.json | python3 -c \
'import sys,yaml,json; print(yaml.dump(json.load(sys.stdin),default_flow_style=False))'
# ===== Ruby one-liner =====
ruby -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.load($stdin.read))' < config.yaml
# ===== Pipe YAML from curl to JSON =====
curl -s https://raw.githubusercontent.com/example/repo/main/config.yaml | \
yq -o=json
# ===== Validate YAML before converting =====
yamllint config.yaml && yq -o=json config.yamlGo (gopkg.in/yaml.v3)
Goではgopkg.in/yaml.v3が堅牢なYAMLパースを提供します:
package main
import (
"encoding/json"
"fmt"
"log"
"gopkg.in/yaml.v3"
)
func main() {
// YAML input string
yamlData := []byte(`
server:
host: localhost
port: 8080
ssl: true
database:
name: myapp
replicas:
- host: db1.example.com
port: 5432
- host: db2.example.com
port: 5432
`)
// Parse YAML into interface{}
var data interface{}
err := yaml.Unmarshal(yamlData, &data)
if err != nil {
log.Fatalf("YAML parse error: %v", err)
}
// Convert map[string]interface{} keys for JSON compatibility
data = convertMapKeys(data)
// Marshal to JSON
jsonData, err := json.MarshalIndent(data, "", " ")
if err != nil {
log.Fatalf("JSON marshal error: %v", err)
}
fmt.Println(string(jsonData))
}
// convertMapKeys recursively converts map[interface{}]interface{}
// to map[string]interface{} for JSON compatibility
func convertMapKeys(v interface{}) interface{} {
switch v := v.(type) {
case map[string]interface{}:
result := make(map[string]interface{})
for key, val := range v {
result[key] = convertMapKeys(val)
}
return result
case []interface{}:
for i, val := range v {
v[i] = convertMapKeys(val)
}
return v
default:
return v
}
}JSONからYAMLへの変換
逆方向の変換も、APIのJSONデータをYAML設定として保存する際に重要です。
コメントは失われます。往復変換でコメントを保持するにはruamel.yamlを使用してください。
ベストプラクティス:2スペースインデント、フロースタイル回避、曖昧な文字列の引用、出力の検証。
よくあるYAMLの落とし穴
YAMLの柔軟性はいくつかの落とし穴を生みます:
タブvsスペース — YAMLはインデントにタブを禁止しています。
ブーリアンの罠 — yes、no、on、offはブーリアンとして解釈されます。
# The YAML boolean trap - these all become true or false in JSON!
# YAML 1.1 boolean values (case-insensitive):
is_active: yes # → true
is_active: no # → false
is_active: on # → true
is_active: off # → false
is_active: y # → true
is_active: n # → false
is_active: true # → true
is_active: false # → false
# Real-world problems:
countries:
- US # string "US" ✓
- GB # string "GB" ✓
- NO # boolean false ✗ (Norway disappears!)
- FR # string "FR" ✓
# Fix: always quote ambiguous values
countries:
- "US"
- "GB"
- "NO" # string "NO" ✓
- "FR"
# Version numbers are also problematic:
version: 1.0 # → float 1 (not string "1.0")
version: "1.0" # → string "1.0" ✓複数行文字列 — |は改行を保持、>はスペースに置換します。
# YAML multiline string variants
# Literal block scalar (|) - preserves newlines
description: |
This is line one.
This is line two.
This is line three.
# JSON: "This is line one.\nThis is line two.\nThis is line three.\n"
# Folded block scalar (>) - replaces newlines with spaces
description: >
This is a long
paragraph that will
be folded into one line.
# JSON: "This is a long paragraph that will be folded into one line.\n"
# Chomping indicators:
keep_trailing: |+ # Keep ALL trailing newlines
text
strip_trailing: |- # Strip ALL trailing newlines
text
clip_trailing: | # Keep exactly ONE trailing newline (default)
text特殊文字 — 値中のコロンや括弧は引用が必要です。
アンカーとエイリアス — JSON変換時に完全展開されます。
# YAML anchors and aliases
# Define an anchor with &
defaults: &default_settings
adapter: postgres
host: localhost
port: 5432
# Reuse with alias *
development:
database:
<<: *default_settings # Merge key: inherits all defaults
database: myapp_dev
production:
database:
<<: *default_settings # Same defaults
database: myapp_prod
host: db.production.com # Override specific values
# After JSON conversion (anchors fully expanded):
# {
# "defaults": { "adapter": "postgres", "host": "localhost", "port": 5432 },
# "development": {
# "database": {
# "adapter": "postgres", "host": "localhost",
# "port": 5432, "database": "myapp_dev"
# }
# },
# "production": {
# "database": {
# "adapter": "postgres", "host": "db.production.com",
# "port": 5432, "database": "myapp_prod"
# }
# }
# }数値と日付の解釈 — 1.0は文字列ではなく浮動小数点になります。
YAMLベストプラクティス
クリーンで保守性の高いYAMLのためのプラクティス:
一貫したインデント — Kubernetes慣例に合わせて2スペース。
防御的な文字列引用 — 迷ったら引用符を使用。
ブーリアンの罠を回避 — 国コードやトグル値に注意。
スキーマ検証 — JSON Schemaで検証。
yamllintを使用 — CI/CDパイプラインに統合。
# .yamllint.yml configuration example
---
extends: default
rules:
line-length:
max: 120
allow-non-breakable-words: true
indentation:
spaces: 2
indent-sequences: true
comments:
min-spaces-from-content: 1
truthy:
check-keys: true
allowed-values: ['true', 'false']
document-start:
present: true
trailing-spaces: enable
new-line-at-end-of-file: enable
# Run yamllint:
# yamllint .
# yamllint config.yaml
# yamllint -d "{extends: default}" config.yaml賢いコメント使用 — JSON変換で失われることを忘れずに。
よくある質問
YAMLとJSONの違いは何ですか?
YAMLはインデントベースでコメントサポートと高度な機能を備えています。JSONはブラケット区切りでコメント非対応、型が限定的です。YAMLは設定ファイル向き、JSONはAPI向きです。
YAMLをJSONに変換するには?
オンラインツール、CLIのyq、またはライブラリ(JavaScript: js-yaml、Python: PyYAML、Go: gopkg.in/yaml.v3)を使用します。
YAMLとJSONはいつ使い分けますか?
YAMLは人間が頻繁に編集する設定ファイル向け。JSONはAPIやサービス間データ交換向けです。
YAMLからJSONへの変換をマスターすることは、現代のDevOpsに不可欠です。無料ツールとYAMLバリデータでワークフローを最適化しましょう。