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 最佳实践清单
- 统一缩进风格:整个项目强制使用 2 空格缩进,禁止混用 Tab 与空格。
- 合理使用注释:在
description字段中写详细说明,YAML 注释仅用于开发备注,不用于最终文档。 - 避免深层嵌套:YAML 嵌套超过 4 层时,考虑使用
$ref引用外部文件或组件。 - 字符串加引号场景:包含冒号、
#、特殊符号的字符串必须加双引号。 - 布尔值统一:统一使用
true/false,避免使用yes/no。 - 文件拆分策略:超过 200 行的 OpenAPI 规范,按
paths/、components/、schemas/拆分多个 YAML 文件。 - 使用 lint 工具:集成
spectral或vacuum进行格式与规范校验。 - JSON 作为交付格式:最终交付给 API 网关或生产环境时,将 YAML 编译为 JSON。
避坑提醒:YAML 中
true、false、yes、no、on、off 会被自动解析为布尔值。如果字段值需要保留为字符串(如 status: "true"),务必加引号。
4.4 YAML 与 JSON 结构对比图
下图展示了同一 OpenAPI 片段在 YAML 与 JSON 中的结构差异,帮助直观理解两种格式的层级表达方式。
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 编译产物,确保人工可读与机器兼容性兼得。