golang多源JSON/YAML/TOML文件合并与验证插件库conflate的使用

Golang多源JSON/YAML/TOML文件合并与验证插件库conflate的使用

gophers

CONFLATE

库提供合并和验证JSON、YAML、TOML文件和/或结构的例程

典型用例:使您的应用程序配置文件支持多格式、模块化、模板化、稀疏、位置独立和验证

描述

Conflate是一个库和CLI工具,提供以下功能:

  • 从多种格式(JSON/YAML/TOML/Go结构体)和多个位置(文件系统路径和URL)合并数据
  • 根据JSON模式验证合并后的数据
  • 将JSON模式中定义的任何默认值应用于合并数据
  • 在数据中扩展环境变量
  • 将合并数据编组为多种格式(JSON/YAML/TOML/Go结构体)

欢迎改进、想法和错误修复。

入门

运行以下命令,将在$GOPATH/bin中构建并安装最新二进制文件:

go install github.com/the4thamigo-uk/conflate/conflate@latest

或者,您可以从发布页面安装预构建的二进制文件。

库的使用

请参考godoc和示例代码。

CLI工具的使用

可以通过以下方式获取帮助:

$conflate --help
Usage of conflate:
  -data value
        The path/url of JSON/YAML/TOML data, or 'stdin' to read from standard input
  -defaults
        Apply defaults from schema to data
  -expand
        Expand environment variables in files
  -format string
        Output format of the data JSON/YAML/TOML
  -includes string
        Name of includes array. Blank string suppresses expansion of includes arrays (default "includes")
  -noincludes
        Switches off conflation of includes. Overrides any --includes setting.
  -schema string
        The path/url of a JSON v4 schema file
  -validate
        Validate the data against the schema
  -version
        Display the version number

通过包含基本合并文件

要合并以下文件:

$cat ./testdata/valid_parent.json
{
  "includes": [
    "valid_child.json",
    "valid_sibling.json"
  ],
  "parent_only" : "parent", 
  "parent_child" : "parent", 
  "parent_sibling" : "parent", 
  "all": "parent"
}

运行以下命令,将合并valid_parent.json、valid_child.json和valid_sibling.json:

$conflate -data ./testdata/valid_parent.json -format JSON
{
  "all": "parent",
  "child_only": "child",
  "parent_child": "parent",
  "parent_only": "parent",
  "parent_sibling": "parent",
  "sibling_child": "sibling",
  "sibling_only": "sibling"
}

选择输出格式

要输出不同格式,使用-format选项,例如TOML:

$conflate -data ./testdata/valid_parent.json -format TOML
all = "parent"
child_only = "child"
parent_child = "parent"
parent_only = "parent"
parent_sibling = "parent"
sibling_child = "sibling"
sibling_only = "sibling"

不使用包含的基本文件合并

如果您不想在JSON中嵌入"includes"数组,可以在命令行上提供多个文件:

$conflate -data ./testdata/valid_child.json -data ./testdata/valid_sibling.json -format JSON
{
  "all": "sibling",
  "child_only": "child",
  "parent_child": "child",
  "parent_sibling": "sibling",
  "sibling_child": "sibling",
  "sibling_only": "sibling"
}

从STDIN合并数据

要从stdin读取文件,使用-data stdin:

$echo 'all="MY OVERRIDDEN VALUE"' |  conflate -data ./testdata/valid_parent.json -data stdin -format JSON
{
  "all": "MY OVERRIDDEN VALUE",
  "child_only": "child",
  "parent_child": "parent",
  "parent_only": "parent",
  "parent_sibling": "parent",
  "sibling_child": "sibling",
  "sibling_only": "sibling"
}

通过包含合并远程文件

如果您将文件托管在其他地方,只需使用URL:

$conflate -data https://raw.githubusercontent.com/the4thamigo-uk/conflate/master/testdata/valid_parent.json -format JSON
{
  "all": "parent",
  "child_only": "child",
  "parent_child": "parent",
  "parent_only": "parent",
  "parent_sibling": "parent",
  "sibling_child": "sibling",
  "sibling_only": "sibling"
}

根据JSON模式验证

要根据JSON模式验证您的数据,使用-schema与-validate组合:

$cat ./testdata/blank.yaml

$conflate -data ./testdata/blank.yaml -schema ./testdata/test.schema.json -validate -format YAML
Schema validation failed : The document is not valid against the schema : Invalid type. Expected: object, given: null (#)

从JSON模式应用默认值

要应用JSON模式中定义的默认值,使用-schema与-defaults组合:

$conflate -data ./testdata/blank.yaml -schema ./testdata/test.schema.json -defaults -validate -format YAML
all: parent
child_only: child
parent_child: parent
parent_only: parent
parent_sibling: parent
sibling_child: sibling
sibling_only: sibling

环境变量的扩展

可以选择在文件中扩展环境变量:

$export echo MYVALUE="some value"
$export echo MYJSONMAP='{ "item1" : "value1" }'
$echo '{ "my_value": "$MYVALUE", "my_map": $MYJSONMAP }' | conflate -data stdin -expand -format JSON
{
  "my_map": {
    "item1": "value1"
  },
  "my_value": "some value"
}

示例代码

package main

import (
	"fmt"
	"github.com/the4thamigo-uk/conflate"
)

func main() {
	// 创建新的合并对象
	c, err := conflate.New()
	if err != nil {
		panic(err)
	}

	// 添加要合并的文件
	err = c.AddFiles("config1.json", "config2.yaml")
	if err != nil {
		panic(err)
	}

	// 添加JSON模式进行验证
	schema, err := conflate.NewSchemaFile("schema.json")
	if err != nil {
		panic(err)
	}

	// 应用默认值并验证
	err = c.ApplyDefaults(schema)
	if err != nil {
		panic(err)
	}
	
	err = c.Validate(schema)
	if err != nil {
		panic(err)
	}

	// 获取合并后的数据
	var data interface{}
	err = c.Unmarshal(&data)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Merged data: %v\n", data)
}

致谢

图像源自Renee French的原创作品。


更多关于golang多源JSON/YAML/TOML文件合并与验证插件库conflate的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang多源JSON/YAML/TOML文件合并与验证插件库conflate的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用conflate库合并与验证多源配置文件

conflate是一个强大的Go库,专门用于合并来自不同源(JSON/YAML/TOML)的配置文件,并支持JSON Schema验证。下面我将详细介绍它的使用方法。

安装conflate

go get github.com/miracl/conflate

基本用法

1. 合并多个配置文件

package main

import (
	"fmt"
	"github.com/miracl/conflate"
)

func main() {
	// 创建新的合并对象
	c, err := conflate.New()
	if err != nil {
		panic(err)
	}

	// 添加要合并的文件
	files := []string{"config1.json", "config2.yaml", "config3.toml"}
	for _, file := range files {
		err = c.AddFiles(file)
		if err != nil {
			panic(err)
		}
	}

	// 合并数据
	var mergedData map[string]interface{}
	err = c.Unmarshal(&mergedData)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Merged config: %+v\n", mergedData)
}

2. 从不同来源合并数据

conflate支持从文件、URL、Go对象和字符串等多种来源合并数据:

// 从URL添加配置
err = c.AddURL("http://example.com/config.json")

// 从Go对象添加配置
data := map[string]interface{}{"key": "value"}
err = c.AddData(data)

// 从字符串添加配置
jsonStr := `{"key": "value"}`
err = c.AddData([]byte(jsonStr))

高级功能

1. 使用JSON Schema验证

func validateWithSchema() {
	c, err := conflate.New()
	if err != nil {
		panic(err)
	}

	// 添加配置文件
	err = c.AddFiles("config.json")
	if err != nil {
		panic(err)
	}

	// 添加JSON Schema文件
	schema, err := conflate.New().AddFiles("schema.json")
	if err != nil {
		panic(err)
	}

	// 验证配置是否符合schema
	err = c.Validate(schema)
	if err != nil {
		fmt.Printf("Validation failed: %v\n", err)
	} else {
		fmt.Println("Configuration is valid")
	}
}

2. 处理合并冲突

conflate提供了几种合并策略:

// 默认合并策略(后添加的覆盖先添加的)
c.SetDefaultMergeStrategy(conflate.MergeStrategy(conflate.StrategyUnion))

// 自定义合并策略
customStrategy := func(dst, src interface{}) (interface{}, error) {
	// 实现自定义合并逻辑
	return dst, nil
}
c.SetMergeFunc(customStrategy)

3. 环境变量替换

conflate支持在配置文件中使用环境变量:

# config.yaml
database:
  host: ${DB_HOST:-localhost}
  port: ${DB_PORT:-5432}
// 启用环境变量扩展
c, err := conflate.New().AddFiles("config.yaml")
if err != nil {
	panic(err)
}

// 应用环境变量替换
err = c.ExpandEnv()
if err != nil {
	panic(err)
}

实际示例

下面是一个完整的示例,展示如何合并多个来源的配置并进行验证:

package main

import (
	"fmt"
	"github.com/miracl/conflate"
)

func main() {
	// 1. 创建合并器
	c, err := conflate.New()
	if err != nil {
		panic(err)
	}

	// 2. 添加多个配置来源
	err = c.AddFiles("base.yaml")                // 基础配置
	err = c.AddURL("http://example.com/overrides.json") // 覆盖配置
	err = c.AddData(map[string]interface{}{      // 默认值
		"logging": map[string]interface{}{
			"level": "info",
		},
	})
	if err != nil {
		panic(err)
	}

	// 3. 应用环境变量替换
	err = c.ExpandEnv()
	if err != nil {
		panic(err)
	}

	// 4. 验证配置
	schema, err := conflate.New().AddFiles("config_schema.json")
	if err != nil {
		panic(err)
	}
	err = c.Validate(schema)
	if err != nil {
		panic(err)
	}

	// 5. 解组到结构体
	var config struct {
		Database struct {
			Host string `json:"host"`
			Port int    `json:"port"`
		} `json:"database"`
		Logging struct {
			Level string `json:"level"`
		} `json:"logging"`
	}

	err = c.Unmarshal(&config)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Final configuration: %+v\n", config)
}

注意事项

  1. 合并顺序很重要 - 后添加的配置会覆盖先添加的配置
  2. 对于复杂结构,确保合并策略符合预期
  3. JSON Schema验证是可选但推荐的功能
  4. 环境变量替换需要在解组前执行

conflate库为Go开发者提供了一个强大而灵活的工具,用于处理现代应用程序中常见的多环境、多来源配置合并问题。通过合理使用它的各种功能,可以大大简化配置管理代码。

回到顶部