JSON vs YAML: Differences, Pros & Cons (With Examples)
Both formats represent the same data, but they make very different trade-offs. Here's how to decide which one fits your use case.
简短回答
当机器是主要受众时使用JSON — API、数据交换、任何被程序解析的内容。当人类是主要受众时使用YAML — 配置文件、CI/CD管道、任何手动编辑的内容。这是一个经验法则,约90%的情况下都适用。
但如果你想了解更全面的情况 — 包括真正的权衡、陷阱,以及在生产中实际重要的细微差别 — 请继续阅读。
并排语法比较
让我们从相同的数据开始,分别用两种格式表示。这是一个典型的Web应用程序配置:
JSON
{
"server": {
"host": "0.0.0.0",
"port": 3000,
"ssl": true
},
"database": {
"driver": "postgres",
"host": "db.example.com",
"port": 5432,
"credentials": {
"username": "app_user",
"password": "s3cret"
},
"pools": [5, 10, 20]
},
"features": {
"darkMode": true,
"betaAccess": false,
"maxUploadSizeMB": 25
}
}
YAML
# 服务器配置
server:
host: "0.0.0.0"
port: 3000
ssl: true
# 数据库设置
database:
driver: postgres
host: db.example.com
port: 5432
credentials:
username: app_user
password: s3cret
pools:
- 5
- 10
- 20
# 功能标志
features:
darkMode: true
betaAccess: false
maxUploadSizeMB: 25
YAML版本更短,包含注释解释每个部分,几乎像是一个项目提纲。JSON版本更明确 — 每个字符串都被引用,结构由大括号和方括号定义,类型没有任何模糊性。
根据我的经验,主要编写代码的开发人员倾向于更喜欢JSON的明确性。DevOps工程师和系统管理员则倾向于更喜欢YAML的可读性。两者都没有错。
即时在格式之间转换: 将JSON粘贴到我们的JSON转YAML转换器中,查看YAML等效项并排显示。或者通过YAML转JSON进行反向转换。
特性比较
| 特性 | JSON | YAML |
|---|---|---|
| 人类可读性 | 良好(带格式) | 优秀 |
| 注释支持 | ❌ 不支持 | ✅ 支持(#语法) |
| 文件大小 | 较大(引号 + 大括号) | 较小(基于缩进) |
| 解析速度 | 非常快 | 较慢(语法更复杂) |
| 机器友好性 | 优秀 | 良好 |
| 人类编辑 | 中等(容易漏掉逗号) | 容易(但对缩进敏感) |
| 缩进敏感性 | 否(空白被忽略) | 是(缩进定义结构) |
| 多行字符串 | 否(使用\n转义) | 是(管道` |
| 锚点和别名 | 否 | 是(使用&和*实现DRY) |
| 原生数据类型 | 6种(字符串、数字、布尔值、null、对象、数组) | 所有JSON类型 + 日期、时间戳、二进制 |
| 规范复杂性 | ~10页 | ~80页 |
| 浏览器支持 | 原生(JSON.parse) | 需要库(js-yaml, yaml) |
何时使用JSON
当数据在系统之间交换而不是被人类读取时,JSON是更好的选择。具体来说:
API和数据交换
每个主要的REST API都使用JSON。GraphQL响应是JSON。Webhook有效负载是JSON。整个Web生态系统围绕Content-Type: application/json构建。使用YAML作为API响应将是逆流而行。
package.json和锁定文件
npm、Yarn和大多数JavaScript工具使用JSON作为其配置和锁定文件。package.json规范要求严格的JSON。你不能添加注释(尽管有一个众所周知的黑客方法使用"//"键),也不能使用尾随逗号。这很烦人,但这是标准。
{
"name": "my-app",
"version": "2.1.0",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "^15.0.0",
"react": "^19.0.0"
}
}
任何需要速度的地方
JSON解析器非常快速,因为语法简单。如果你在管道中处理数百万条消息,JSON在解析性能上相对于YAML的优势是显著的。我们在大多数基准测试中谈论的是5-10倍的速度。
何时使用YAML
当人类编写和维护文件时,YAML表现优异。DevOps领域在很大程度上已经标准化为YAML,原因很充分。
Docker Compose
version: "3.8"
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- db
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: secret
volumes:
pgdata:
尝试用JSON编写这个,你会立刻明白为什么Docker选择YAML。嵌套结构自然可读,注释让你可以注解各个部分,而缺少闭合大括号使得内容保持整洁。
Kubernetes清单
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
Kubernetes YAML文件可能会变得非常庞大。如果没有注释和基于缩进的清晰结构,它们将难以维护。尽管如此,即使使用YAML,大型K8s配置仍然相当痛苦 — 这就是为什么像Helm和Kustomize这样的工具存在的原因。
CI/CD管道
GitHub Actions、GitLab CI、CircleCI和大多数CI平台使用YAML进行管道定义。能够添加内联注释来解释为什么某个步骤存在,在你凌晨2点调试失败的构建时是非常有价值的。
常见陷阱
YAML陷阱
- 挪威问题: 在YAML 1.1中,
NO被解释为布尔值false。国家代码、缩写和其他短字符串可能会被静默误解。YAML 1.2修复了这个问题,但一些解析器仍然使用旧规范。始终引用可能模糊的字符串。 - 缩进错误是静默的: 错误的缩进级别并不总是导致解析错误 — 它可能只是创建了与你意图不同的结构。这是我经验中YAML错误的主要来源。
- 禁止使用制表符: YAML只允许使用空格进行缩进。混入制表符会导致神秘的解析错误。
- 安全问题: YAML的
!!python/object标签(及类似标签)在解析时可能执行任意代码。始终使用安全加载函数。
JSON陷阱
- 没有注释。 你会想念它们。每个人都会想念它们。一些工具支持JSONC,但标准JSON不支持。
- 尾随逗号陷阱: JavaScript允许你使用尾随逗号。JSON不允许。在两者之间复制粘贴会经常让你受伤。
- 数字精度: JSON数字是IEEE 754双精度。大整数(超过2^53)会失去精度。如果你处理大ID,请将它们作为字符串传递。
- 没有多行字符串: 长文本值需要
\n转义序列,这使得文件更难以阅读。
自己试试: 使用我们的JSON转YAML转换器将复杂的JSON文件转换为YAML,看看结构在两种格式之间是如何映射的。或者先用JSON验证器验证你的JSON。
可以同时使用两者吗?
绝对可以,大多数项目都是如此。一个典型的Node.js项目可能有package.json(JSON)和docker-compose.yml(YAML)以及.github/workflows/ci.yml(YAML)。混合使用格式没有问题 — 使用工具所期望的格式或在上下文中更有意义的格式。
一个重要的细节:YAML是JSON的超集(自YAML 1.2起)。这意味着每个有效的JSON文档也是有效的YAML。因此,如果你将JSON粘贴到YAML解析器中,它将正常工作。反之则不然 — YAML有JSON不支持的特性。
性能比较
如果性能对你的用例很重要,JSON明显胜出。以下是解析相同1MB文档的粗略数字:
| 操作 | JSON | YAML |
|---|---|---|
| 解析时间(Node.js) | ~15ms | ~120ms |
| 字符串化时间 | ~10ms | ~80ms |
| 文件大小(格式化后) | 1.00 MB | 0.75 MB |
| 文件大小(压缩后) | 0.60 MB | N/A(YAML不能真正压缩) |
YAML文件较小,因为它们跳过引号和大括号,但解析所需的时间显著更长。对于在启动时读取一次的配置文件,这并不重要。对于每天处理数百万次的API有效负载,这非常重要。
最终结论
我建议将JSON作为数据交换的默认选择,将YAML用于配置。如果工具给你选择,考虑谁将阅读和编辑文件。机器?JSON。人类?YAML。两者?先使用JSON,看看没有注释的痛苦是否会推动你转向YAML。
如果你是JSON的新手,请从我们的什么是JSON?指南开始,了解基础知识。
相关工具:
- JSON转YAML转换器
- YAML转JSON转换器
- JSON格式化工具
- JSON与XML — 另一个常见格式比较