← 返回博客首页

JSON vs YAML vs TOML:配置文件格式对比与选型指南

三种格式概览

在现代软件开发中,配置文件无处不在——从 package.jsondocker-compose.yml 再到 pyproject.toml。JSON、YAML 和 TOML 是三种最主流的结构化数据格式,各自有独特的设计哲学和适用场景。选错格式可能导致维护噩梦,选对格式则能大幅提升开发体验。

一句话总结

  • JSON:通用数据交换格式,机器友好,严格规范
  • YAML:人类可读的配置格式,表现力强,但规则复杂
  • TOML:专为配置文件设计,语义明确,类型系统完善

JSON

JSON(JavaScript Object Notation)源于 JavaScript,但已成为跨语言数据交换的事实标准。它被 RFC 8259 标准化,几乎所有编程语言都内置了 JSON 解析器。

语法特点

{
  "name": "oltools",
  "version": "1.0.0",
  "features": ["json", "yaml", "toml"],
  "config": {
    "debug": true,
    "port": 8080
  }
}

优点

  • 通用性极强:所有语言、所有平台都原生支持
  • 语法严格:解析器实现简单,行为一致
  • 性能优秀:解析速度快,适合高频数据传输
  • 标准完善:RFC 8259 + ECMA-404 双重标准

缺点

  • 不支持注释:配置文件无法添加说明,这是最大痛点
  • 不支持多行字符串:长文本必须用 \n 转义,可读性差
  • 键名必须加双引号:书写冗余
  • 不允许尾随逗号:修改时容易出错
  • 只有一种数据类型表示数字:大整数可能丢失精度

适用场景

  • ✅ API 数据交换(REST、GraphQL 响应)
  • ✅ NoSQL 数据库存储(MongoDB、DynamoDB)
  • ✅ 程序间通信(消息队列、WebHook)
  • ❌ 人工编辑的配置文件
  • ❌ 需要注释的复杂配置

YAML

YAML(YAML Ain't Markup Language)以可读性为核心设计目标,广泛用于 CI/CD 配置、容器编排等场景。

语法特点

name: oltools
version: 1.0.0
features:
  - json
  - yaml
  - toml
config:
  debug: true
  port: 8080

优点

  • 极高的可读性:缩进表达层级,视觉清晰
  • 支持注释# 注释,适合配置文件
  • 支持多行字符串| 保留换行,> 折叠换行
  • 支持引用&anchor 定义,*alias 引用,避免重复
  • 类型推断:自动识别字符串、数字、布尔值、null

缺点

  • 缩进敏感:空格数量必须一致,Tab 不被允许,极易出错
  • 隐式类型转换陷阱yes/no/on/off 会被解析为布尔值,3.10 会被解析为数字 3.1
  • 规范极其复杂:YAML 1.2 规范超过 80 页,不同解析器行为可能不一致
  • 安全性问题:部分解析器支持任意对象实例化,存在反序列化攻击风险
  • 不支持原生 Date 类型的统一处理

常见陷阱示例

# 以下内容可能不符合预期
version: 1.10      # 解析为数字 1.1,而非字符串 "1.10"
enabled: no         # 解析为布尔值 false,而非字符串 "no"
date: 2025-04-10    # 可能被解析为日期对象
port: 0800          # 解析为八进制 512

解决方案:对字符串值始终加引号。

适用场景

  • ✅ CI/CD 配置(GitHub Actions、GitLab CI)
  • ✅ 容器编排(Docker Compose、Kubernetes)
  • ✅ 静态站点生成器(Hugo、Jekyll)
  • ❌ 机器生成/解析的数据交换
  • ❌ 对安全性要求极高的场景

TOML

TOML(Tom's Obvious, Minimal Language)专为配置文件设计,目标是成为 JSON 和 YAML 在配置领域的替代品。已被 Python(PEP 518 pyproject.toml)、Rust(Cargo.toml)、Go 等生态广泛采用。

语法特点

name = "oltools"
version = "1.0.0"
features = ["json", "yaml", "toml"]

[config]
debug = true
port = 8080

[servers.alpha]
ip = "10.0.0.1"
port = 8080

优点

  • 语义明确:每种数据类型有清晰的表示方式,无隐式转换
  • 支持注释# 注释
  • 多行字符串"""...""" 三引号
  • 丰富的类型系统:原生支持日期时间、数组、表(Table)
  • 规范简洁:TOML 1.0 规范可读性强,解析器行为一致
  • 无缩进陷阱:使用 [section] 显式表达层级

缺点

  • 深层嵌套不友好:超过 3 层嵌套时,表路径变得冗长
  • 生态成熟度:虽然主流语言都有解析器,但不如 JSON 普及
  • 不适合大型数据集:设计目标是配置而非数据交换

适用场景

  • ✅ 项目配置文件(pyproject.tomlCargo.toml
  • ✅ 应用配置(config.toml
  • ✅ 需要日期时间类型的配置
  • ❌ API 数据交换
  • ❌ 深层嵌套数据结构

三者对比一览

特性 JSON YAML TOML
注释
多行字符串
日期时间类型 部分
引用/锚点
缩进敏感
类型推断 隐式 显式
可读性 一般 优秀 优秀
生态普及度 极高
安全性 优秀 需注意 优秀
适用场景 数据交换 复杂配置 项目配置

选型建议

按场景选择

  1. API 数据交换 → JSON(无可争议)
  2. CI/CD 与容器编排 → YAML(生态绑定)
  3. 项目/应用配置 → TOML(现代首选)
  4. 需要人类频繁编辑的配置 → TOML 或 YAML
  5. 需要程序生成的数据 → JSON

趋势判断

TOML 正在快速取代 INI 和部分 YAML 场景。Python、Rust、Go 生态已全面拥抱 TOML。如果你启动新项目且配置文件需要人工维护,TOML 是 2025 年最推荐的格式。YAML 在 CI/CD 和容器领域仍是事实标准,短期内不会被替代。JSON 作为数据交换格式的地位则不可撼动。

格式互转注意事项

在不同格式间转换时,需注意:

  • JSON → YAML:通常安全
  • YAML → JSON:注意隐式类型转换,yes 会变成 true
  • TOML → JSON:日期时间类型可能丢失语义
  • 任何方向转换:注释都会丢失

建议使用各语言的专用库进行转换,而非手动改写。

← 返回博客首页