JSON 与 YAML:您应该使用哪种配置格式?
快速解答
将 JSON 用于 APIs、数据交换以及严格解析和验证很重要的情况。将 YAML 用于配置文件、DevOps 清单以及人类可读性和注释很重要的情况。 YAML 是 JSON 超集 — 每个有效的 JSON 文档都是有效的 YAML。
介绍
JSON 和 YAML 都是人类可读的数据序列化格式。 JSON 在网络 APIs 中是严格的、最小的且普遍存在的。 YAML 是 JSON 的超集,它添加了注释、多行字符串、锚点和基于缩进的结构,使其在配置文件(Docker Compose、Kubernetes、CI/CD 管道)中很受欢迎。
步步
-
比较语法和可读性
JSON 使用大括号和引号:{"key": "value"}。 YAML 使用缩进和冒号:键:值。 YAML 的配置更加简洁——字符串不需要引号,项目之间不需要逗号,也不需要大括号。 JSON 对于数据交换来说更加明确且不易出错。
-
比较功能
YAML 支持:注释 (#)、多行字符串 (|、>)、锚点 (&) 和别名 (*)、一个文件中的多个文档 (---) 以及复杂类型。 JSON 不支持这些——没有注释,没有多行字符串,没有引用。 JSON 的简单性是有意为之的:它是一种数据交换格式,而不是一种配置语言。
-
比较安全性和解析
JSON 解析快速且安全 — JSON.parse 内置于每个 JavaScript 引擎中。 YAML 解析速度更慢、更复杂 — YAML 规范有 80 多页,而 JSON 只有 2 页。 YAML 存在安全风险(通过锚点进行数十亿笑声攻击),而 JSON 则没有。始终使用禁用锚点的安全 YAML 解析器。
-
比较生态系统使用情况
JSON:REST APIs、package.json、tsconfig.json、NoSQL 数据库、Web 应用程序。 YAML:Docker Compose、Kubernetes 清单、GitHub Actions、Ansible playbook、CI/CD 配置、OpenAPI 规范。 JSON 控制运行时数据; YAML 主导配置。
-
根据您的用例决定
APIs,数据交换,NoSQL,Web 应用程序状态:JSON。配置文件、DevOps、CI/CD、基础设施即代码:YAML。如果是人类手写的话:YAML。如果机器生成并消耗它:JSON。
示例
JSON 和 YAML 中的配置相同
输入: JSON: {"server": {"port": 8080, "host": "localhost"}}
YAML: server:\n port: 8080\n host: localhost
输出: YAML 缩短了 30%,并且支持注释。 JSON 更严格且普遍可解析。
常见问题
- YAML 缩进错误:YAML 使用缩进进行结构,并且单个错误的空格会中断解析 - 使用具有 YAML linting 的编辑器并始终使用空格,而不是制表符。
- YAML 十亿笑攻击:YAML 锚点和别名可以创建指数扩展,导致 DoS - 使用禁用锚点的安全 YAML 解析器(例如 Python 中的 yaml.safe_load)。
- JSON 没有注释:JSON 规范禁止注释,使配置文件更难注释——使用 YAML 进行人工编辑的配置,使用 JSON 处理机器生成的数据。
- YAML 隐式类型令人惊讶:YAML 自动将 yes/no 转换为布尔值,将 1.0 自动转换为浮点数,这可能会破坏字符串字段 - 显式引用字符串以避免意外的类型强制。
提示
- 使用 YAML 进行人工编写的配置(Docker Compose、Kubernetes、CI/CD),使用 JSON 进行机器生成的数据交换(APIs、NoSQL、应用程序状态)。
- 始终使用禁用锚点和别名的安全 YAML 解析器 - 切勿在不受信任的输入上使用通用 YAML 加载器。
- 将 YAML 转换为 JSON 时,预计会丢失注释、多行字符串和锚点 — JSON 是 YAML 的子集,而不是功能的相反方式。
- 始终使用 2 个空格缩进 YAML — 混合制表符和空格或使用不一致的缩进是最常见的 YAML 解析错误。