Complete Configuration File Formats Complete Guide | JSON, YAML, XML, TOML, INI Comparison
이 글의 핵심
Characteristics and differences of frequently used file formats in programming including JSON, YAML, XML, TOML, INI, Markdown. Complete understanding with pros/cons, use cases, parsing methods, and practical examples.
Introduction: The Importance of Configuration File Formats
Every programming project uses configuration files. package.json, docker-compose.yml, nginx.conf, README.md - each format has different characteristics and purposes. Choosing the right format greatly improves code readability and maintainability.
Formats covered in this article:
- JSON (JavaScript Object Notation)
- YAML (YAML Ain’t Markup Language)
- XML (eXtensible Markup Language)
- TOML (Tom’s Obvious, Minimal Language)
- INI (Initialization File)
- Markdown
- Others (Properties, HCL, Jsonnet)
Reality in Practice
When learning development, everything is clean and theoretical. But practice is different. You wrestle with legacy code, chase tight deadlines, and face unexpected bugs. The content covered in this article was initially learned as theory, but through applying it to real projects, I realized “Ah, this is why it’s designed this way.” What’s particularly memorable are the trial and errors from my first project. I did it as the book taught, but couldn’t figure out why it didn’t work for days. Eventually, I found the problem through a senior developer’s code review, and learned a lot in the process. This article covers not only theory but also pitfalls you might encounter in practice and their solutions.
Table of Contents
- JSON
- YAML
- XML
- TOML
- INI
- Markdown
- Format Comparison and Selection Guide
- Practical Conversion and Validation
1. JSON (JavaScript Object Notation)
What is JSON?
JSON is a lightweight data interchange format based on JavaScript object notation. It’s easy for humans to read and easy for machines to parse.
JSON Basic Syntax
Here’s a detailed implementation using JSON. Please review the code to understand the role of each part.
{
"name": "John Doe",
"age": 30,
"email": "[email protected]",
"isActive": true,
"balance": 1234.56,
"tags": ["developer", "designer"],
"address": {
"street": "123 Main St",
"city": "Seoul",
"zipCode": "12345"
},
"projects": [
{
"id": 1,
"name": "Project A",
"status": "active"
},
{
"id": 2,
"name": "Project B",
"status": "completed"
}
],
"metadata": null
}
JSON Data Types
Here’s an implementation example using JSON. Please review the code to understand the role of each part.
{
"string": "Hello, World!",
"number": 42,
"float": 3.14159,
"boolean": true,
"null": null,
"array": [1, 2, 3, "mixed", true],
"object": {
"nested": "value"
}
}
JSON Pros and Cons
Here’s a detailed implementation using mermaid. Please review the code to understand the role of each part.
flowchart TB
JSON[JSON]
subgraph Pros[Advantages]
P1[✅ Fast parsing]
P2[✅ JavaScript native]
P3[✅ Concise syntax]
P4[✅ Widely supported]
end
subgraph Cons[Disadvantages]
C1[❌ No comments]
C2[❌ No trailing commas]
C3[❌ Inconvenient multiline strings]
C4[❌ No date type]
end
JSON --> Pros
JSON --> Cons
JSON Usage Examples
Here’s an implementation example using JavaScript. Please review the code to understand the role of each part.
// JavaScript
const config = {
apiUrl: "https://api.example.com",
timeout: 5000,
retries: 3
};
// Convert to JSON
const json = JSON.stringify(config, null, 2);
console.log(json);
// Parse JSON
const parsed = JSON.parse(json);
console.log(parsed.apiUrl);
Here’s a detailed implementation using Python. Import necessary modules. Please review the code to understand the role of each part.
# Python
import json
config = {
"apiUrl": "https://api.example.com",
"timeout": 5000,
"retries": 3
}
# Convert to JSON
json_str = json.dumps(config, indent=2)
print(json_str)
# Parse JSON
parsed = json.loads(json_str)
print(parsed['apiUrl'])
# File I/O
with open('config.json', 'w') as f:
json.dump(config, f, indent=2)
with open('config.json', 'r') as f:
loaded = json.load(f)
JSON Schema (Validation)
Here’s a detailed implementation using JSON. Please review the code to understand the role of each part.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
},
"email": {
"type": "string",
"format": "email"
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"required": ["name", "email"]
}
2. YAML (YAML Ain’t Markup Language)
What is YAML?
YAML is a human-readable data serialization format. It expresses hierarchy through indentation and supports comments.
YAML Basic Syntax
Here’s a detailed implementation using YAML. Ensure stability with error handling. Please review the code to understand the role of each part.
# Comments start with #
# Key-value pairs
name: John Doe
age: 30
email: [email protected]
# Boolean
isActive: true
isDeleted: false
# Null
metadata: null
# or
metadata: ~
# Strings (quotes optional)
city: Seoul
country: "South Korea"
description: 'Single quotes.. Complete Configuration File Formats Complete Guide에 대한 완전한 가이드입니다. 실전 예제와 함께 핵심 개념부터 고급 활용까지 다룹니다.' # Multiline strings
bio: |
This is a multi-line string.
It preserves line breaks.
Very useful for long text.
summary: >
This is a folded string.
Line breaks are converted to spaces.
Useful for long paragraphs.
# Arrays (lists)
tags:
- developer
- designer
- writer
# Or inline
tags: ["developer", "designer", "writer"]
# Objects (dictionaries)
address:
street: 123 Main St
city: Seoul
zipCode: "12345"
# Or inline
address: {street: 123 Main St, city: Seoul, zipCode: "12345"}
# Arrays + Objects
projects:
- id: 1
name: Project A
status: active
- id: 2
name: Project B
status: completed
# Anchors and aliases (reuse)
defaults: &defaults
timeout: 30
retries: 3
production:
<<: *defaults
apiUrl: https://api.example.com
development:
<<: *defaults
apiUrl: http://localhost:3000
YAML Cautions
Here’s a detailed implementation using YAML. Ensure stability with error handling. Please review the code to understand the role of each part.
# ❌ No tabs (spaces only)
name: value
nested: error # Error if indented with tabs!
# ✅ Use spaces
name: value
nested: correct
# ❌ Inconsistent indentation
items:
- name: item1
value: 100
- name: item2 # Indentation error!
# ✅ Consistent indentation
items:
- name: item1
value: 100
- name: item2
value: 200
# Special character caution
# Strings with colons (:) need quotes
url: "https://example.com" # Quotes recommended
time: "12:30" # Quotes required
# Strings starting with numbers
version: "1.0" # Quotes needed (otherwise parsed as number)
YAML Usage Examples
Here’s a detailed implementation using Python. Import necessary modules. Please review the code to understand the role of each part.
# Python
import yaml
config = {
'name': 'MyApp',
'version': '1.0.0',
'database': {
'host': 'localhost',
'port': 5432,
'name': 'mydb'
},
'features': ['auth', 'api', 'admin']
}
# Convert to YAML
yaml_str = yaml.dump(config, default_flow_style=False)
print(yaml_str)
# Parse YAML
parsed = yaml.safe_load(yaml_str)
print(parsed['database']['host'])
# File I/O
with open('config.yaml', 'w') as f:
yaml.dump(config, f, default_flow_style=False)
with open('config.yaml', 'r') as f:
loaded = yaml.safe_load(f)
Docker Compose Example
Here’s a detailed implementation using YAML. Please review the code to understand the role of each part.
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./html:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/nginx.conf:ro
environment:
- NGINX_HOST=example.com
- NGINX_PORT=80
depends_on:
- app
networks:
- webnet
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
app:
build:
context: .
dockerfile: Dockerfile
args:
- NODE_ENV=production
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
- REDIS_URL=redis://redis:6379
volumes:
- ./app:/app
- /app/node_modules
networks:
- webnet
deploy:
replicas: 3
resources:
limits:
cpus: '0.5'
memory: 512M
db:
image: postgres:15
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- db-data:/var/lib/postgresql/data
networks:
- webnet
networks:
webnet:
driver: bridge
volumes:
db-data:
3. XML (eXtensible Markup Language)
What is XML?
XML is an extensible markup language that structures data based on tags. It supports strict syntax and schema validation.
XML Basic Syntax
Here’s a detailed implementation using XML. Please review the code to understand the role of each part.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Comment -->
<configuration>
<!-- Simple elements -->
<name>MyApp</name>
<version>1.0.0</version>
<!-- Attributes -->
<database type="postgresql" ssl="true">
<host>localhost</host>
<port>5432</port>
<name>mydb</name>
<credentials>
<username>user</username>
<password>pass</password>
</credentials>
</database>
<!-- Arrays (repeated elements) -->
<features>
<feature name="auth" enabled="true"/>
<feature name="api" enabled="true"/>
<feature name="admin" enabled="false"/>
</features>
<!-- CDATA (includes special characters) -->
<description><![CDATA[
This is a <description> with special characters: & < > " '
]]></description>
<!-- Namespaces -->
<config xmlns="http://example.com/config"
xmlns:db="http://example.com/database">
<db:connection>localhost</db:connection>
</config>
</configuration>
XML Parsing
Here’s a detailed implementation using Python. Import necessary modules. Please review the code to understand the role of each part.
# Python (ElementTree)
import xml.etree.ElementTree as ET
# Parse XML
tree = ET.parse('config.xml')
root = tree.getroot()
# Access elements
name = root.find('name').text
print(f"Name: {name}")
# Access attributes
db = root.find('database')
db_type = db.get('type')
print(f"Database type: {db_type}")
# Repeated elements
for feature in root.findall('.//feature'):
name = feature.get('name')
enabled = feature.get('enabled')
print(f"Feature {name}: {enabled}")
# Using XPath
host = root.find('.//database/host').text
print(f"Database host: {host}")
Here’s an implementation example using JavaScript. Please review the code to understand the role of each part.
// JavaScript (Browser)
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
// Access elements
const name = xmlDoc.getElementsByTagName("name")[0].textContent;
console.log(name);
// Access attributes
const db = xmlDoc.getElementsByTagName("database")[0];
const dbType = db.getAttribute("type");
console.log(dbType);
XML Schema (XSD)
Here’s a detailed implementation using XML. Please review the code to understand the role of each part.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="configuration">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="version" type="xs:string"/>
<xs:element name="database" type="DatabaseType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="DatabaseType">
<xs:sequence>
<xs:element name="host" type="xs:string"/>
<xs:element name="port" type="xs:integer"/>
</xs:sequence>
<xs:attribute name="type" type="xs:string" use="required"/>
</xs:complexType>
</xs:schema>
XML Use Cases
Here’s a detailed implementation using XML. Please review the code to understand the role of each part.
<!-- Maven (pom.xml) -->
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>myapp</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>
</project>
<!-- Spring (applicationContext.xml) -->
<beans xmlns="http://www.springframework.org/schema/beans">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/mydb"/>
</bean>
</beans>
<!-- Android (AndroidManifest.xml) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<uses-permission android:name="android.permission.INTERNET"/>
<application android:label="MyApp">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
</application>
</manifest>
4. TOML (Tom’s Obvious, Minimal Language)
What is TOML?
TOML is an easy-to-read and clear configuration file format. It’s an improved version of INI, supporting types and nesting.
TOML Basic Syntax
Here’s a detailed implementation using TOML. Please review the code to understand the role of each part.
# Comment
# Key-value pairs
name = "MyApp"
version = "1.0.0"
# Numbers
port = 8080
timeout = 30.5
# Boolean
debug = true
production = false
# Date/time
created_at = 2026-04-01T10:00:00Z
# Arrays
tags = ["rust", "web", "api"]
# Inline tables
author = { name = "John Doe", email = "[email protected]" }
# Tables (sections)
[database]
host = "localhost"
port = 5432
name = "mydb"
[database.credentials]
username = "user"
password = "pass"
# Array of tables
[[servers]]
name = "server1"
ip = "192.168.1.1"
role = "primary"
[[servers]]
name = "server2"
ip = "192.168.1.2"
role = "backup"
# Nested structure
[app.cache]
enabled = true
ttl = 3600
[app.cache.redis]
host = "localhost"
port = 6379
TOML Parsing
Here’s a detailed implementation using Python. Import necessary modules. Please review the code to understand the role of each part.
# Python
import tomli # Python 3.11+ has built-in tomllib
with open('config.toml', 'rb') as f:
config = tomli.load(f)
print(config['name'])
print(config['database']['host'])
print(config['servers'][0]['name'])
# Generate TOML
import tomli_w
data = {
'name': 'MyApp',
'version': '1.0.0',
'database': {
'host': 'localhost',
'port': 5432
}
}
with open('output.toml', 'wb') as f:
tomli_w.dump(data, f)
Here’s a detailed implementation using Rust. Define classes to encapsulate data and functionality, implement logic through functions. Please review the code to understand the role of each part.
// Rust
use serde::Deserialize;
use std::fs;
#[derive(Deserialize)]
struct Config {
name: String,
version: String,
database: Database,
}
#[derive(Deserialize)]
struct Database {
host: String,
port: u16,
}
fn main() {
let contents = fs::read_to_string("config.toml").unwrap();
let config: Config = toml::from_str(&contents).unwrap();
println!("Name: {}", config.name);
println!("DB Host: {}", config.database.host);
}
TOML Use Cases
Here’s a detailed implementation using TOML. Please review the code to understand the role of each part.
# Cargo.toml (Rust)
[package]
name = "myapp"
version = "0.1.0"
edition = "2021"
[dependencies]
tokio = { version = "1.35", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[dev-dependencies]
criterion = "0.5"
[profile.release]
opt-level = 3
lto = true
# pyproject.toml (Python)
[project]
name = "myapp"
version = "1.0.0"
description = "My Python application"
authors = [{name = "John Doe", email = "[email protected]"}]
dependencies = [
"fastapi>=0.104.0",
"uvicorn>=0.24.0",
]
[project.optional-dependencies]
dev = ["pytest>=7.4.0", "black>=23.0.0"]
[tool.black]
line-length = 88
target-version = ['py311']
5. INI (Initialization File)
What is INI?
INI is a simple configuration file format widely used in Windows. It consists of sections and key-value pairs.
INI Basic Syntax
Here’s a detailed implementation using INI. Define classes to encapsulate data and functionality. Please review the code to understand the role of each part.
; Comments start with semicolon
# Or hash (#) is also possible
; Global settings (no section)
app_name = MyApp
version = 1.0.0
; Section
[database]
host = localhost
port = 5432
name = mydb
username = user
password = pass
[cache]
enabled = true
ttl = 3600
type = redis
[cache.redis]
host = localhost
port = 6379
; Arrays (non-standard, varies by implementation)
[features]
feature1 = auth
feature2 = api
feature3 = admin
; Or
features = auth,api,admin
INI Parsing
Here’s a detailed implementation using Python. Import necessary modules. Please review the code to understand the role of each part.
# Python
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
# Read values
app_name = config['DEFAULT']['app_name']
db_host = config['database']['host']
db_port = config.getint('database', 'port')
cache_enabled = config.getboolean('cache', 'enabled')
print(f"App: {app_name}")
print(f"DB: {db_host}:{db_port}")
print(f"Cache: {cache_enabled}")
# Write values
config['database']['host'] = 'db.example.com'
with open('config.ini', 'w') as f:
config.write(f)
INI Use Cases
Here’s a detailed implementation using INI. Please review the code to understand the role of each part.
; php.ini
[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
serialize_precision = -1
disable_functions = exec,passthru,shell_exec,system
[Date]
date.timezone = Asia/Seoul
[Session]
session.save_handler = files
session.save_path = "/var/lib/php/sessions"
session.gc_maxlifetime = 1440
; .gitconfig
[user]
name = John Doe
email = [email protected]
[core]
editor = vim
autocrlf = input
[alias]
st = status
co = checkout
br = branch
ci = commit
6. Markdown
What is Markdown?
Markdown is a lightweight markup language for writing formatted documents in plain text.
Markdown Basic Syntax
Here’s a detailed implementation using Markdown. Please review the code to understand the role of each part.
# Heading 1 (H1)
## Heading 2 (H2)
### Heading 3 (H3)
**Bold** or __Bold__
*Italic* or _Italic_
~~Strikethrough~~
`Inline code`
> Blockquote
> Multiple lines possible
- Unordered list
- Item 2
- Nested item
- Nested item 2
1. Ordered list
2. Item 2
3. Item 3
[Link text](https://example.com)

---
Horizontal rule
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Value 1 | Value 2 | Value 3 |
| Value 4 | Value 5 | Value 6 |
```code block```
Multiple lines of code
```python
# Language specification (syntax highlighting)
def hello():
print("Hello, World!")
- Checkbox (incomplete)
- Checkbox (complete)
### GitHub Flavored Markdown (GFM)
Here's a detailed implementation using Markdown. Please review the code to understand the role of each part.
```markdown
# GitHub Extensions
## Task Lists
- [x] Completed task
- [ ] Incomplete task
- [ ] In progress
## Table Alignment
| Left | Center | Right |
|:-----|:------:|------:|
| Left | Center | Right |
## Emoji
:smile: :rocket: :tada:
## Mentions
@username
## Issue References
#123
## Code Block with Filename
```javascript:app.js
console.log("Hello");
Collapsible Sections
Click to expand
Hidden content$E = mc^2$ $$ \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} $$
### Markdown Parsing
Here's a detailed implementation using Python. Import necessary modules. Please review the code to understand the role of each part.
```python
# Python (markdown library)
import markdown
md_text = """
# Hello
This is **bold** and *italic*.
- Item 1
- Item 2
"""
html = markdown.markdown(md_text)
print(html)
# <h1>Hello</h1>
# <p>This is <strong>bold</strong> and <em>italic</em>.</p>
# <ul>
# <li>Item 1</li>
# <li>Item 2</li>
# </ul>
# Using extensions
html = markdown.markdown(md_text, extensions=['tables', 'fenced_code', 'toc'])
Here’s an implementation example using JavaScript. Import necessary modules. Please review the code to understand the role of each part.
// JavaScript (marked library)
import { marked } from 'marked';
const mdText = `
# Hello
This is **bold** text.
`;
const html = marked.parse(mdText);
console.log(html);
7. Format Comparison and Selection Guide
Same Data Representation
JSON
Here’s an implementation example using JSON. Please review the code to understand the role of each part.
{
"app": {
"name": "MyApp",
"version": "1.0.0",
"features": ["auth", "api"]
},
"database": {
"host": "localhost",
"port": 5432
}
}
YAML
Here’s an implementation example using YAML. Please review the code to understand the role of each part.
# Example
app:
name: MyApp
version: 1.0.0
features:
- auth
- api
database:
host: localhost
port: 5432
XML
Here’s a detailed implementation using XML. Please review the code to understand the role of each part.
<?xml version="1.0"?>
<config>
<app>
<name>MyApp</name>
<version>1.0.0</version>
<features>
<feature>auth</feature>
<feature>api</feature>
</features>
</app>
<database>
<host>localhost</host>
<port>5432</port>
</database>
</config>
TOML
Here’s an implementation example using TOML. Try running the code directly to see how it works.
# Example
[app]
name = "MyApp"
version = "1.0.0"
features = ["auth", "api"]
[database]
host = "localhost"
port = 5432
INI
Here’s an implementation example using INI. Try running the code directly to see how it works.
[app]
name = MyApp
version = 1.0.0
features = auth,api
[database]
host = localhost
port = 5432
Comparison Table
| Feature | JSON | YAML | XML | TOML | INI | Markdown |
|---|---|---|---|---|---|---|
| Readability | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Parsing Speed | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Comments | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Type Safety | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ | N/A |
| Nested Structure | ✅ | ✅ | ✅ | ✅ | Limited | ✅ |
| File Size | Small | Medium | Large | Medium | Small | Medium |
| Schema Validation | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Recommendations by Use Case
Here’s a detailed implementation using mermaid. Please review the code to understand the role of each part.
flowchart TD
Start[Choose File Format] --> Q1{Purpose?}
Q1 -->|API Response| JSON["✅ JSON\nFast parsing"]
Q1 -->|Config File| Q2{Complexity?}
Q1 -->|Documentation| Markdown["✅ Markdown\nREADME, blog"]
Q1 -->|Build Config| Q3{Language?}
Q2 -->|Simple| INI["✅ INI\nSimple config"]
Q2 -->|Medium| TOML["✅ TOML\nRust, Python"]
Q2 -->|Complex| YAML["✅ YAML\nDocker, K8s"]
Q3 -->|Java| XML["✅ XML\nMaven, Spring"]
Q3 -->|JavaScript| JSON["✅ JSON\npackage.json"]
Q3 -->|Rust| TOML["✅ TOML\nCargo.toml"]
Q3 -->|Python| TOML2["✅ TOML\npyproject.toml"]
Project Usage
| Project | Format | Filename |
|---|---|---|
| Node.js | JSON | package.json |
| Python | TOML | pyproject.toml |
| Rust | TOML | Cargo.toml |
| Go | Go | go.mod |
| Docker | YAML | docker-compose.yml |
| Kubernetes | YAML | deployment.yaml |
| Ansible | YAML | playbook.yml |
| Maven | XML | pom.xml |
| Gradle | Groovy | build.gradle |
| Nginx | Custom | nginx.conf |
| Apache | Custom | httpd.conf |
8. Practical Conversion and Validation
Format Conversion
Here’s a detailed implementation using Python. Import necessary modules, define classes to encapsulate data and functionality. Please review the code to understand the role of each part.
#!/usr/bin/env python3
"""
Configuration file format conversion tool
"""
import json
import yaml
import tomli
import tomli_w
import xml.etree.ElementTree as ET
from pathlib import Path
class ConfigConverter:
@staticmethod
def json_to_yaml(json_file, yaml_file):
"""JSON → YAML"""
with open(json_file, 'r') as f:
data = json.load(f)
with open(yaml_file, 'w') as f:
yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
print(f"✅ Converted: {json_file} → {yaml_file}")
@staticmethod
def yaml_to_json(yaml_file, json_file):
"""YAML → JSON"""
with open(yaml_file, 'r') as f:
data = yaml.safe_load(f)
with open(json_file, 'w') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print(f"✅ Converted: {yaml_file} → {json_file}")
@staticmethod
def json_to_toml(json_file, toml_file):
"""JSON → TOML"""
with open(json_file, 'r') as f:
data = json.load(f)
with open(toml_file, 'wb') as f:
tomli_w.dump(data, f)
print(f"✅ Converted: {json_file} → {toml_file}")
@staticmethod
def toml_to_json(toml_file, json_file):
"""TOML → JSON"""
with open(toml_file, 'rb') as f:
data = tomli.load(f)
with open(json_file, 'w') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print(f"✅ Converted: {toml_file} → {json_file}")
# Usage
converter = ConfigConverter()
converter.json_to_yaml('config.json', 'config.yaml')
converter.yaml_to_json('config.yaml', 'config.json')
converter.json_to_toml('config.json', 'config.toml')
Validation Tools
Here’s a detailed implementation using bash. Please review the code to understand the role of each part.
# JSON validation
jq . config.json
# or
python -m json.tool config.json
# YAML validation
yamllint config.yaml
# YAML → JSON (yq)
yq eval -o=json config.yaml
# XML validation
xmllint --noout config.xml
# TOML validation (Python)
python -c "import tomli; tomli.load(open('config.toml', 'rb'))"
Online Tools
Here’s a detailed implementation using bash. Please review the code to understand the role of each part.
# jq (JSON query)
cat config.json | jq '.database.host'
# "localhost"
# Array filtering
cat config.json | jq '.servers[] | select(.role == "primary")'
# Conversion
cat config.json | jq '.database'
# yq (YAML query)
cat config.yaml | yq '.database.host'
# xmllint (XML query)
xmllint --xpath '//database/host/text()' config.xml
Other Formats
Properties (Java)
Here’s a detailed implementation using properties. Please review the code to understand the role of each part.
# application.properties (Spring Boot)
server.port=8080
server.address=0.0.0.0
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=user
spring.datasource.password=pass
# Arrays
spring.profiles.active=dev,debug
# Multiline (backslash)
app.description=This is a very long \
description that spans \
multiple lines.
HCL (HashiCorp Configuration Language)
Here’s a detailed implementation using HCL. Please review the code to understand the role of each part.
# Terraform
variable "region" {
description = "AWS region"
type = string
default = "us-west-2"
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
Environment = "production"
}
}
output "instance_ip" {
value = aws_instance.web.public_ip
}
Jsonnet (JSON Template)
Here’s a detailed implementation using Jsonnet. Please review the code to understand the role of each part.
// config.jsonnet
local env = std.extVar('env');
local base = {
name: 'MyApp',
version: '1.0.0',
};
local envConfig = {
dev: {
apiUrl: 'http://localhost:3000',
debug: true,
},
prod: {
apiUrl: 'https://api.example.com',
debug: false,
},
};
base + envConfig[env]
Here’s an implementation example using bash. Try running the code directly to see how it works.
# Execute
jsonnet -V env=dev config.jsonnet
# {
# "name": "MyApp",
# "version": "1.0.0",
# "apiUrl": "http://localhost:3000",
# "debug": true
# }
ENV Files
Here’s an implementation example using bash. Please review the code to understand the role of each part.
# .env
NODE_ENV=production
PORT=3000
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
REDIS_URL=redis://localhost:6379
API_KEY=secret-key-123
DEBUG=false
# Arrays (non-standard)
ALLOWED_HOSTS=localhost,example.com,*.example.com
Here’s an implementation example using Python. Import necessary modules. Please review the code to understand the role of each part.
# Python (python-dotenv)
from dotenv import load_dotenv
import os
load_dotenv()
port = int(os.getenv('PORT', 3000))
database_url = os.getenv('DATABASE_URL')
debug = os.getenv('DEBUG', 'false').lower() == 'true'
print(f"Port: {port}")
print(f"Database: {database_url}")
print(f"Debug: {debug}")
Practical Tips
1. Comments
Here’s a detailed implementation using JavaScript. Please review the code to understand the role of each part.
// JSON doesn't support comments → Use JSON5
// package.json5
{
// Project info
name: "myapp",
version: "1.0.0",
// Dependencies
dependencies: {
express: "^4.18.0", // Trailing commas allowed
},
}
// Or use _comment key (non-standard)
{
"_comment": "This is a comment",
"name": "myapp"
}
2. Environment-specific Configuration
Here’s an implementation example using YAML. Please review the code to understand the role of each part.
# config.yaml
default: &default
timeout: 30
retries: 3
development:
<<: *default
apiUrl: http://localhost:3000
debug: true
production:
<<: *default
apiUrl: https://api.example.com
debug: false
Here’s an implementation example using Python. Import necessary modules. Please review the code to understand the role of each part.
# Load by environment with Python
import yaml
import os
env = os.getenv('ENV', 'development')
with open('config.yaml') as f:
config = yaml.safe_load(f)
app_config = config[env]
print(app_config)
3. Sensitive Information Management
Here’s an implementation example using YAML. Please review the code to understand the role of each part.
# config.yaml (exclude sensitive info)
database:
host: localhost
port: 5432
name: mydb
# username and password from environment variables
# .env (exclude from version control)
DB_USERNAME=user
DB_PASSWORD=secret
# .gitignore
.env
*.secret.yaml
Here’s an implementation example using Python. Import necessary modules. Please review the code to understand the role of each part.
# Merge with Python
import yaml
import os
with open('config.yaml') as f:
config = yaml.safe_load(f)
# Override with environment variables
config['database']['username'] = os.getenv('DB_USERNAME')
config['database']['password'] = os.getenv('DB_PASSWORD')
4. Schema Validation
Here’s a detailed implementation using Python. Import necessary modules, ensure stability with error handling. Please review the code to understand the role of each part.
# JSON Schema validation
import json
import jsonschema
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer", "minimum": 0}
},
"required": ["name"]
}
data = {"name": "John", "age": 30}
try:
jsonschema.validate(data, schema)
print("✅ Valid")
except jsonschema.ValidationError as e:
print(f"❌ Invalid: {e.message}")
Summary
Format Selection Flowchart
Here’s a detailed implementation using mermaid. Please review the code to understand the role of each part.
flowchart TD
Start[Choose Config File Format] --> Q1{Need comments?}
Q1 -->|No| Q2{Parsing speed important?}
Q1 -->|Yes| Q3{Complexity?}
Q2 -->|Yes| JSON["✅ JSON\n- API response\n- Fast parsing"]
Q2 -->|No| Q3
Q3 -->|Simple| INI["✅ INI\n- Simple config\n- Legacy compat"]
Q3 -->|Medium| TOML["✅ TOML\n- Python/Rust\n- Clear syntax"]
Q3 -->|Complex| YAML["✅ YAML\n- Docker/K8s\n- Best readability"]
Start --> Q4{Documentation?}
Q4 -->|Yes| MD["✅ Markdown\n- README\n- Blog"]
Start --> Q5{Java project?}
Q5 -->|Yes| XML["✅ XML\n- Maven\n- Spring"]
Core Principles
Here’s a detailed implementation using Python. Implement logic through functions. Please review the code to understand the role of each part.
# 1. API response → JSON
@app.get("/api/users")
def get_users():
return {"users": [...]} # JSON
# 2. Config file → YAML or TOML
# config.yaml
database:
host: localhost
port: 5432
# 3. Documentation → Markdown
# README.md
# My Project
This is a description.
# 4. Build config → By language
# package.json (Node.js)
# Cargo.toml (Rust)
# pom.xml (Java)
# 5. Simple config → INI
# app.ini
[database]
host = localhost
Pros and Cons Summary
| Format | Best Advantage | Biggest Disadvantage | Recommended Use |
|---|---|---|---|
| JSON | Fast parsing | No comments | API, data exchange |
| YAML | Readability | Slow parsing | Docker, K8s, CI/CD |
| XML | Schema validation | Verbose | Java, SOAP, RSS |
| TOML | Clear syntax | Limited support | Rust, Python config |
| INI | Simplicity | No standard | Simple config |
| Markdown | Easy to read | Limited data structure | Docs, README |
Best Practices
Here’s a detailed implementation using YAML. Please review the code to understand the role of each part.
# ✅ Recommendations
# 1. Consistent indentation (YAML)
app:
name: MyApp # 2 spaces
version: 1.0.0
# 2. Use comments (YAML, TOML)
# Database configuration
[database]
host = "localhost" # localhost in dev environment
# 3. Separate environment variables
# config.yaml (version controlled)
database:
host: ${DB_HOST}
port: ${DB_PORT}
# .env (excluded from version control)
DB_HOST=localhost
DB_PORT=5432
# 4. Schema validation
# Use JSON Schema, YAML Schema
# 5. Encrypt sensitive information
# Use SOPS, Vault, etc.
Conversion Cheat Sheet
Command Line Tools
Here’s a detailed implementation using bash. Please review the code to understand the role of each part.
# JSON → YAML
cat config.json | yq -P > config.yaml
# YAML → JSON
cat config.yaml | yq -o=json > config.json
# JSON formatting
cat config.json | jq . > formatted.json
# YAML validation
yamllint config.yaml
# XML formatting
xmllint --format config.xml
# JSON merge
jq -s '.[0] * .[1]' base.json override.json > merged.json
# YAML merge
yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' base.yaml override.yaml
By Programming Language
Here’s a detailed implementation using Python. Import necessary modules. Please review the code to understand the role of each part.
# Python: All formats supported
import json # Built-in
import yaml # pip install pyyaml
import tomli # pip install tomli
import configparser # Built-in (INI)
import xml.etree.ElementTree as ET # Built-in
# JavaScript/Node.js
const json = require('./config.json'); # Native
const yaml = require('js-yaml');
const toml = require('toml');
const ini = require('ini');
# Go
import (
"encoding/json"
"gopkg.in/yaml.v3"
"github.com/BurntSushi/toml"
"gopkg.in/ini.v1"
)
# Rust
use serde_json; // JSON
use serde_yaml; // YAML
use toml; // TOML
Summary
One-line summary: Use JSON for APIs, YAML or TOML for config files, Markdown for documentation, XML for Java builds, but understand the pros and cons of each format and choose based on project requirements.