三种格式概览
在现代软件开发中,配置文件无处不在——从 package.json 到 docker-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.toml、Cargo.toml) - ✅ 应用配置(
config.toml) - ✅ 需要日期时间类型的配置
- ❌ API 数据交换
- ❌ 深层嵌套数据结构
三者对比一览
| 特性 | JSON | YAML | TOML |
|---|---|---|---|
| 注释 | ❌ | ✅ | ✅ |
| 多行字符串 | ❌ | ✅ | ✅ |
| 日期时间类型 | ❌ | 部分 | ✅ |
| 引用/锚点 | ❌ | ✅ | ❌ |
| 缩进敏感 | ❌ | ✅ | ❌ |
| 类型推断 | 无 | 隐式 | 显式 |
| 可读性 | 一般 | 优秀 | 优秀 |
| 生态普及度 | 极高 | 高 | 中 |
| 安全性 | 优秀 | 需注意 | 优秀 |
| 适用场景 | 数据交换 | 复杂配置 | 项目配置 |
选型建议
按场景选择
- API 数据交换 → JSON(无可争议)
- CI/CD 与容器编排 → YAML(生态绑定)
- 项目/应用配置 → TOML(现代首选)
- 需要人类频繁编辑的配置 → TOML 或 YAML
- 需要程序生成的数据 → JSON
趋势判断
TOML 正在快速取代 INI 和部分 YAML 场景。Python、Rust、Go 生态已全面拥抱 TOML。如果你启动新项目且配置文件需要人工维护,TOML 是 2025 年最推荐的格式。YAML 在 CI/CD 和容器领域仍是事实标准,短期内不会被替代。JSON 作为数据交换格式的地位则不可撼动。
格式互转注意事项
在不同格式间转换时,需注意:
- JSON → YAML:通常安全
- YAML → JSON:注意隐式类型转换,
yes会变成true - TOML → JSON:日期时间类型可能丢失语义
- 任何方向转换:注释都会丢失
建议使用各语言的专用库进行转换,而非手动改写。