본문으로 건너뛰기 Complete Configuration File Formats Complete Guide | JSON, YAML, XML, TOML, INI Comparison

Complete Configuration File Formats Complete Guide | JSON, YAML, XML, TOML, INI Comparison

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

  1. JSON
  2. YAML
  3. XML
  4. TOML
  5. INI
  6. Markdown
  7. Format Comparison and Selection Guide
  8. 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)
![Image alt text](image.png)
---
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
## Math (LaTeX)

$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

FeatureJSONYAMLXMLTOMLINIMarkdown
Readability⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Parsing Speed⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Comments
Type Safety⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐N/A
Nested StructureLimited
File SizeSmallMediumLargeMediumSmallMedium
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

ProjectFormatFilename
Node.jsJSONpackage.json
PythonTOMLpyproject.toml
RustTOMLCargo.toml
GoGogo.mod
DockerYAMLdocker-compose.yml
KubernetesYAMLdeployment.yaml
AnsibleYAMLplaybook.yml
MavenXMLpom.xml
GradleGroovybuild.gradle
NginxCustomnginx.conf
ApacheCustomhttpd.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

FormatBest AdvantageBiggest DisadvantageRecommended Use
JSONFast parsingNo commentsAPI, data exchange
YAMLReadabilitySlow parsingDocker, K8s, CI/CD
XMLSchema validationVerboseJava, SOAP, RSS
TOMLClear syntaxLimited supportRust, Python config
INISimplicityNo standardSimple config
MarkdownEasy to readLimited data structureDocs, 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.