4、YAML与JSON基础:YAML语法入门、JSON语法对比、OpenAPI推荐格式与最佳实践

在 OpenAPI 接口契约设计中,描述文件的选择直接影响团队协作效率与工具链兼容性。YAML 与 JSON 是 OpenAPI 规范官方支持的两种序列化格式。本章将系统讲解 YAML 核心语法、与 JSON 的差异对比,并给出 OpenAPI 场景下的推荐格式与最佳实践。

4.1 YAML 语法入门

YAML(YAML Ain't Markup Language)是一种以缩进为核心的数据序列化格式,强调人类可读性。OpenAPI 3.x 规范中,YAML 是官方首选描述格式。

4.1.1 基础语法规则

规则 说明 正确示例 错误示例
缩进 使用空格(推荐 2 个),禁止使用 Tab name: John \tname: John
键值对 key: value,冒号后必须跟空格 age: 30 age:30
注释 使用 # 开头,仅支持单行 # 这是注释 /* 多行注释 */
字符串 一般无需引号,特殊字符需加引号 title: 用户接口 title: 用户:接口
列表 以 - 开头,缩进对齐 - item1 * item1

4.1.2 核心数据结构

# 标量(Scalar)
name: 张三
age: 28
active: true
score: 95.5

# 列表(Sequence)
tags:
  - user
  - admin
  - manager

# 映射(Mapping)
address:
  city: 北京
  district: 海淀
  zip: "100000"

# 嵌套结构
user:
  id: 1001
  roles:
    - reader
    - writer
  profile:
    avatar: /images/avatar.png
    bio: 全栈工程师

4.1.3 多行字符串与锚点

# 保留换行(|)
description: |
  这是一个多行描述。
  第二行内容。
  第三行内容。

# 折叠换行(>)
summary: >
  这是一个折叠的
  长文本,最终会
  合并为一行。

# 锚点与引用(& / *)
base: &default
  timeout: 30
  retry: 3

service_a:
  <<: *default
  url: /api/a

service_b:
  <<: *default
  url: /api/b
  timeout: 60  # 覆盖默认值
提示:YAML 锚点(&)与合并(<<:)在 OpenAPI 中可用于复用公共响应体或参数定义,但过度使用会降低可读性,建议仅在 2-3 层嵌套内使用。

4.2 JSON 语法对比

JSON(JavaScript Object Notation)是另一种广泛使用的数据格式,在 OpenAPI 工具链中兼容性最佳。以下从语法、可读性、工具支持三个维度进行对比。

4.2.1 语法差异对照表

特性 YAML JSON
缩进 空格缩进,2 空格标准 不依赖缩进,花括号包裹
注释 支持 # 单行注释 不支持注释
字符串引号 大多数字符串无需引号 必须使用双引号
布尔值 true / false / yes / no 仅 true / false
数字类型 自动识别整数/浮点数 自动识别整数/浮点数
空值 null 或留空 null
多行字符串 支持 | 和 > 需使用 \n 转义
锚点/引用 支持 & / * 不支持
文件大小 通常比 JSON 小 15%-25% 较大,引号和大括号冗余

4.2.2 同一数据两种格式对比

# YAML 版本
openapi: "3.0.3"
info:
  title: 用户服务
  version: "1.0.0"
paths:
  /users:
    get:
      summary: 获取用户列表
      parameters:
        - name: page
          in: query
          schema:
            type: integer
      responses:
        "200":
          description: 成功
// JSON 版本
{
  "openapi": "3.0.3",
  "info": {
    "title": "用户服务",
    "version": "1.0.0"
  },
  "paths": {
    "/users": {
      "get": {
        "summary": "获取用户列表",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "成功"
          }
        }
      }
    }
  }
}
关键差异:YAML 版本比 JSON 版本减少约 40% 的字符数,且无需处理大括号嵌套层级,人工审查效率更高。但 JSON 在机器解析速度上通常比 YAML 快 2-3 倍。

4.3 OpenAPI 推荐格式与最佳实践

基于社区实践与工具链兼容性,OpenAPI 官方及主流工具(Swagger Editor、Redoc、Stoplight)均推荐 YAML 作为首选描述格式。以下给出具体推荐策略。

4.3.1 格式选择决策矩阵

场景 推荐格式 理由
人工编写与审查 YAML 可读性强,支持注释,缩进结构清晰
CI/CD 自动化校验 JSON 解析速度快,无歧义,工具支持成熟
版本控制(Git) YAML 差异对比更直观,合并冲突易处理
API 网关导入 JSON 多数网关原生支持 JSON 导入
团队协作(多人编辑) YAML 支持注释说明字段含义,降低沟通成本
大规模规范(>5000 行) JSON YAML 缩进错误风险随行数增加

4.3.2 最佳实践清单

  1. 统一缩进风格:整个项目强制使用 2 空格缩进,禁止混用 Tab 与空格。
  2. 合理使用注释:在 description 字段中写详细说明,YAML 注释仅用于开发备注,不用于最终文档。
  3. 避免深层嵌套:YAML 嵌套超过 4 层时,考虑使用 $ref 引用外部文件或组件。
  4. 字符串加引号场景:包含冒号、#、特殊符号的字符串必须加双引号。
  5. 布尔值统一:统一使用 true / false,避免使用 yes / no。
  6. 文件拆分策略:超过 200 行的 OpenAPI 规范,按 paths/、components/、schemas/ 拆分多个 YAML 文件。
  7. 使用 lint 工具:集成 spectral 或 vacuum 进行格式与规范校验。
  8. JSON 作为交付格式:最终交付给 API 网关或生产环境时,将 YAML 编译为 JSON。
避坑提醒:YAML 中 true、false、yes、no、on、off 会被自动解析为布尔值。如果字段值需要保留为字符串(如 status: "true"),务必加引号。

4.4 YAML 与 JSON 结构对比图

下图展示了同一 OpenAPI 片段在 YAML 与 JSON 中的结构差异,帮助直观理解两种格式的层级表达方式。

YAML 与 JSON 结构对比 YAML 结构 openapi: "3.0.3" info: (title, version) paths: /users → get parameters: (name, in, schema) responses: "200" → description # 支持注释 缩进驱动 · 无引号 · 可读性强 JSON 结构 "openapi": "3.0.3" "info": { "title", "version" } "paths": { "/users": { "get" } } "parameters": [ { "name", "in" } ] "responses": { "200": { } } // 不支持注释 花括号驱动 · 必须引号 · 机器友好

4.5 格式转换与工具链

在实际项目中,经常需要在 YAML 与 JSON 之间互转。以下列出常用工具与命令。

工具 命令/用法 适用场景
yq yq -o=json input.yaml > output.json 命令行快速转换
jq jq -c . input.json | yq -P > output.yaml 管道处理与格式化
Swagger Editor 在线编辑器支持一键转换 可视化编辑与预览
js-yaml (Node.js) yaml.load() / yaml.dump() 程序化处理
PyYAML (Python) yaml.safe_load() / yaml.dump() Python 项目集成
推荐工作流:开发阶段使用 YAML 编写 OpenAPI 规范,利用 yq 或 Swagger Editor 转换为 JSON 后提交至 API 网关。在 Git 仓库中同时维护 .yaml 源文件和 .json 编译产物,确保人工可读与机器兼容性兼得。