在 YAML 中如何将 JSON 对象作为字符串整体赋值?——兼谈 Go Template 中的 fromJson 使用

在日常开发中,我们经常需要在配置文件(如 YAML)中嵌入一段 JSON 数据。有时,这段 JSON 并不是要被 YAML 解析器当作结构化对象处理,而是作为一个完整的字符串 传递给下游系统(比如 Go 模板、Helm Chart 或微服务配置)。那么,如何在 YAML 中正确地将一个 JSON 对象表示为字符串?本文将为你详细解答,并结合 Go Template 中的 fromJson 函数说明其典型应用场景。


一、问题背景

假设我们有如下 JSON 数据:

json 复制代码
{
  "name": "Alice",
  "age": 30,
  "hobbies": ["reading", "swimming"]
}

现在,我们需要将它作为一个字符串赋值给 YAML 文件中的某个字段,例如:

yaml 复制代码
data: ??? # 这里应该填什么?

注意:我们的目标是让 data 的值是一个字符串,而不是一个 YAML 映射(map)!


二、错误做法:直接写成 YAML 结构

很多初学者会这样写:

yaml 复制代码
# ❌ 错误!这会被解析为 map,不是字符串
data:
  name: Alice
  age: 30
  hobbies:
    - reading
    - swimming

这样写虽然语义上等价,但 data 是一个对象(map) ,而不是字符串。如果你后续要用 fromJson 去解析它,就会失败------因为它根本就不是 JSON 字符串!


三、正确做法:将 JSON 作为字符串嵌入 YAML

✅ 方法 1:使用单引号包裹(推荐)

yaml 复制代码
data: '{"name": "Alice", "age": 30, "hobbies": ["reading", "swimming"]}'
  • 单引号内的内容在 YAML 中不会转义,原样保留。
  • 简洁、安全、可读性好。
  • 是最常用的方式。

✅ 方法 2:使用双引号 + 转义(不推荐,但合法)

yaml 复制代码
data: "{\"name\": \"Alice\", \"age\": 30, \"hobbies\": [\"reading\", \"swimming\"]}"
  • 需要手动转义内部的双引号,容易出错。
  • 仅在特殊场景下使用。

✅ 方法 3:使用折叠块标量 >-(适合长 JSON)

yaml 复制代码
data: >-
  {"name": "Alice", "age": 30, "hobbies": ["reading", "swimming"]}
  • >- 表示"折叠换行并去除末尾换行",最终得到单行字符串。
  • 如果你为了可读性想分行写 JSON,需谨慎:YAML 会把换行转为空格,可能导致 JSON 格式错误。

🚫 不要使用 |(保留换行),因为会在字符串末尾添加 \n,破坏 JSON 合法性。


四、实际应用场景:Go Template 中的 fromJson

在 Helm、Kubernetes 或自定义 Go 应用中,我们常通过模板动态渲染配置。此时,fromJson 就派上用场了。

1. 定义 fromJson 函数

go 复制代码
func fromJSON(jsonStr string) interface{} {
    var result interface{}
    if err := json.Unmarshal([]byte(jsonStr), &result); err != nil {
        return map[string]interface{}{} // 安全兜底
    }
    return result
}

2. 注册到模板函数

go 复制代码
tmpl := template.Must(template.New("example").Funcs(template.FuncMap{
    "fromJson": fromJSON,
}).Parse(`...`))

3. 在模板中使用

假设 values.yaml 如下:

yaml 复制代码
userData: '{"name": "Alice", "age": 30, "hobbies": ["reading", "swimming"]}'

模板内容:

go 复制代码
{{- $user := fromJson .Values.userData }}
Name: {{ $user.name }}
Age: {{ $user.age }}
Hobbies: {{ join ", " $user.hobbies }}

输出结果:

复制代码
Name: Alice
Age: 30
Hobbies: reading, swimming

✅ 成功将 YAML 中的 JSON 字符串解析为结构化数据!


五、总结

场景 推荐写法
短 JSON 字符串 '{"key":"value"}'(单引号)
长 JSON(需换行) 谨慎使用 >-,确保无格式破坏
避免 直接写 YAML 结构(会被解析为 map)

记住:当你需要把 JSON 当作字符串传递时,必须用引号包裹,防止 YAML 解析器将其结构化。


六、延伸阅读


💡 小贴士 :在 Helm 中,官方已内置 fromJsontoJSON 函数,无需手动实现!

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、转发!也欢迎在评论区交流你在 YAML/JSON 处理中遇到的坑 😊

相关推荐
雨中飘荡的记忆1 天前
ElasticJob分布式调度从入门到实战
java·后端
考虑考虑1 天前
JDK25模块导入声明
java·后端·java ee
_小马快跑_1 天前
Java 的 8 大基本数据类型:为何是不可或缺的设计?
java
Re_zero1 天前
线上日志被清空?这段仅10行的 IO 代码里竟然藏着3个毒瘤
java·后端
洋洋技术笔记1 天前
Spring Boot条件注解详解
java·spring boot
程序员清风2 天前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5512 天前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
华仔啊2 天前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing3 天前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员
日月云棠3 天前
各版本JDK对比:JDK 25 特性详解
java