同一份数据 YAML 和 JSON 长什么样

YAML 和 JSON 都常用来写配置文件,表达的数据是一样的,只是格式不同。先看一个简单的例子,同一个服务器配置分别用这两种格式来表达:

YAML 写法
server:
  host: localhost
  port: 8080
  ssl:
    enabled: true
    cert_path: /etc/ssl/cert.pem
database:
  driver: postgres
  host: db.example.com
  port: 5432
  name: myapp
  pool_size: 10
JSON 写法
{
  "server": {
    "host": "localhost",
    "port": 8080,
    "ssl": {
      "enabled": true,
      "cert_path": "/etc/ssl/cert.pem"
    }
  },
  "database": {
    "driver": "postgres",
    "host": "db.example.com",
    "port": 5432,
    "name": "myapp",
    "pool_size": 10
  }
}

可以看出 YAML 版本明显更短,省掉了所有的引号、逗号和大括号,靠缩进来表示层级关系。JSON 版本则结构更明确——大括号和方括号让嵌套关系一目了然,机器解析起来也更简单。

为什么需要互相转换

不同场景下对格式有不同的偏好,所以经常要在两者之间切换。

Docker Compose / Kubernetes 用 YAML

如果你写过 Docker Compose 的 docker-compose.yml 或者 Kubernetes 的部署清单,会发现它们几乎都是 YAML。原因很简单:这类配置通常嵌套层次深,用 JSON 写的话括号堆叠会很密集,可读性差。YAML 的缩进风格在这种场景下看着舒服不少。

程序生成和交换数据用 JSON

JSON 是 JavaScript 原生支持的格式,前后端 API 交互、配置导出、日志记录等场景下几乎是事实标准。大部分编程语言的 JSON 解析库都是内置的,性能好且稳定。另外 JSON 的语法严格,不容易因为格式问题产生歧义,适合机器之间的数据交换。

CI/CD 配置文件

GitLab CI、GitHub Actions 这些流水线的配置文件也主要用 YAML。因为这类文件经常要人工编辑和维护,YAML 的可读性优势在这里体现得更明显。

国际化 / 多语言文件

i18n 的翻译文件以前常用 JSON,现在也有不少项目改用 YAML 来管理。具体用哪种往往取决于团队习惯和所用框架的约定。

YAML 缩进有什么坑

YAML 用缩进来决定层级,这一点既是优点也是坑的来源。下面这几个问题最常见:

空格 vs Tab

硬性规定:YAML 只接受空格缩进,Tab 字符会导致解析错误。而且缩进量必须一致——不能混用 2 个空格和 4 个空格。大多数编辑器打开 .yml 文件时会自动把 Tab 转成空格,但如果用记事本之类的工具手动编辑就容易中招。

缩进一致性

# 正确:同层级的 key 缩进一致
server:
  host: localhost
  port: 8080        # 这里也是 2 个空格

# 错误:port 多了一个空格,变成 server 的子级了
server:
  host: localhost
    port: 8080      # 解析结果可能出乎意料

这种错误肉眼很难发现,因为只差一个字符的位置。用格式化工具统一处理一遍能有效避免这类问题。

特殊字符需要引号

# 冒号后面紧跟空格的内容会被当值
# 但如果值本身包含冒号或其他特殊字符就要加引号
time: "12:00:00"
description: "This is a string with: colon and 'quotes'"

布尔值的歧义

YAML 里 true/falseyes/noon/off 都会被当作布尔值解析。如果你想存一个字面字符串 "yes",就得加上引号:answer: "yes"。这个行为在不同 YAML 解析器的实现上偶尔会有细微差别,也是出 bug 的重灾区。

YAML 和 JSON 互转该往哪个方向转

实际工作中怎么选,主要看你手里的数据和目标用途:

  • JSON 转 YAML:拿到了一段 API 返回的 JSON 或者某个工具导出的 JSON 配置,想用人眼读或者手动编辑 → 转成 YAML 更方便
  • YAML 转 JSON:需要把 Docker / K8s 的配置传给某个只能接收 JSON 的程序,或者要做 diff 对比 → 转成 JSON
  • 验证格式:不确定自己写的 YAML 语法有没有问题 → 先转成 JSON 再转回 YAML,如果两次转换结果一致说明格式没问题
  • 缩小体积:某些场景下 JSON 去掉多余空白后比 YAML 更紧凑 → 传输时可以考虑转成压缩后的 JSON

转换过程中要注意一点:YAML 支持注释(# 开头的那行),而 JSON 不支持。所以 YAML 转 JSON 会丢失所有注释信息。如果你的注释里有重要的说明,转换前最好单独备份一份。

提示

不管用哪种格式,关键是要保持项目内的一致性。不要同一个仓库里一部分配置用 YAML 一部分用 JSON,除非有充分的理由。混着来会增加团队成员的认知负担,也容易在复制粘贴时引入格式错误。

常见问题

YAML 转 JSON 会丢失注释吗?

会。JSON 格式不支持注释,所以 YAML 中的注释转成 JSON 后会消失。如果注释很重要,建议在 YAML 文件中维护,JSON 版本只用于程序读取。从 JSON 转回 YAML 时注释也无法恢复。

YAML 里的锚点和引用转 JSON 会怎样?

YAML 支持锚点(&anchor)和引用(*anchor)来避免重复。转成 JSON 时,引用会被展开成完整的数据副本。也就是说,原本用引用复用的数据,在 JSON 里会变成多份独立的拷贝,文件体积会变大。

转换报错怎么排查?

最常见的原因是 YAML 缩进不一致——同一层级必须用相同数量的空格,不能用 Tab。其次是特殊字符没加引号,比如值里包含冒号、方括号等。把报错信息里指出的行号对应到源文件检查即可。