golang支持多格式结构化数据配置解析插件库confiq的使用

golang支持多格式结构化数据配置解析插件库confiq的使用

godoc for greencoda/confiq Go 1.22

confiq 是一个 Go 包,用于从 JSON、TOML、YAML 或 Env 等结构化数据格式填充结构体或数组,通过使用结构体标签将加载的值映射到字段,使用可以按键遍历映射和按索引遍历数组的选择器路径语法。

数据可以从文件、字符串、字节数组、读取器中加载,在环境变量格式的情况下可以从实际环境中加载。

安装

go get -u github.com/greencoda/confiq

示例

提供支持格式的配置数据:

config.json

{
    "serverHost": "http://localhost",
    "port": 8000,
    "settings": {
        "readOnlyMode": true,
        "maxConnections": 10,
        "disallowedUsernames": ["badUser1", "badUser2"]
    },
    "apiKeys": [
        "testKey1",
        "testKey2"
    ]
}

使用 confiq.New 创建一个新的 configSet,并根据您希望提供数据的方式使用适当的 Load 方法加载数据。在这个例子中,我们从文件系统加载它:

configSet := confiq.New()

if err := configSet.Load(
    confiqjson.Load().FromFile("./config.json"),
); err != nil {
    log.Fatal(err)
}

定义配置结构体并在其结构体标签中为每个字段提供映射。

您可以将某些字段定义为 required,或者如果它不是必需的则具有 default 值(这些是互斥的),或者将某些字段标记为 strict,如果无法从提供的配置数据设置值,这将导致整个解码过程失败。

type Config struct {
	ServerHost          *url.URL `cfg:"serverHost,required"`
	ServerPort          string   `cfg:"port"`
	AllowedUsernames    []string `cfg:"settings.allowedUsernames,default=root;admin;developer"`
	DisallowedUsernames []string `cfg:"settings.disallowedUsernames"`
	ReadOnlyMode        bool     `cfg:"settings.readOnlyMode"`
	MaxConnections      int      `cfg:"settings.maxConnections"`
	ClientID            string   `cfg:"settings.clientId,default=defaultClient"`
	APIKey              string   `cfg:"apiKeys[1]"`
}

var config Config

然后使用 Decode 从加载的配置数据解码数据到这个结构体:

if err := configSet.Decode(&config); err != nil {
   // ...
}

您也可以使用 confiq.AsStrict() 选项使所有字段表现得好像它们是 strict

if err := configSet.Decode(&config, confiq.AsStrict()); err != nil {
   // ...
}

结果将是一个从配置文件的指定地址加载数据的结构体实例:

(main.Config) {
 ServerHost: (*url.URL)(0xc0000e2090)(http://localhost),
 ServerPort: (string) (len=4) "8000",
 AllowedUsernames: ([]string) (len=3 cap=3) {
  (string) (len=4) "root",
  (string) (len=5) "admin",
  (string) (len=9) "developer"
 },
 DisallowedUsernames: ([]string) (len=2 cap=2) {
  (string) (len=8) "badUser1",
  (string) (len=8) "badUser2"
 },
 ReadOnlyMode: (bool) true,
 MaxConnections: (int) 10,
 ClientID: (string) (len=13) "defaultClient",
 APIKey: (string) (len=8) "testKey2"
}

支持的类型

confiq 支持递归地将值解码为具有导出字段的结构体、映射和切片。

结构体

  • 具有其他支持类型的导出字段的结构体

映射

  • 具有原始类型键和其他支持类型值的映射

切片

  • 其他支持类型的切片
  • 字符串将在分号处拆分,并尝试解码为其他支持类型的切片

原始类型

  • string
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • bool

其他常见类型

  • json.RawMessage
  • net.IP
  • time.Duration
  • time.Time
  • *url.URL

自定义类型

  • 实现 Decoder 接口的结构体
  • 实现 encoding.TextUnmarshaler 接口的类型

指针

  • 也支持指向支持类型的指针

为自定义结构体定义解码器

对于具有自定义结构体类型的字段,您可以通过为您的类型指定 Decode 方法来实现 Decoder 接口:

type customType struct {
	Value string
}

func (t *customType) Decode(value any) error {
	if stringValue, ok := value.(string); !ok {
		return errors.New("value is not a string")
	} else {
		t.Value = stringValue

		return nil
	}
}

更多关于golang支持多格式结构化数据配置解析插件库confiq的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang支持多格式结构化数据配置解析插件库confiq的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


confiq - Go语言多格式配置解析库

confiq是一个轻量级的Go语言配置解析库,支持多种格式的配置文件解析,包括JSON、YAML、TOML、INI等。下面我将详细介绍confiq的使用方法和示例代码。

安装

go get github.com/greaka/confiq

基本用法

1. 加载配置文件

package main

import (
	"fmt"
	"github.com/greaka/confiq"
)

func main() {
	// 创建一个配置容器
	container := confiq.New()

	// 加载JSON配置文件
	if err := container.Load("config.json", confiq.JSON); err != nil {
		fmt.Printf("加载JSON配置失败: %v\n", err)
	}

	// 加载YAML配置文件
	if err := container.Load("config.yaml", confiq.YAML); err != nil {
		fmt.Printf("加载YAML配置失败: %v\n", err)
	}

	// 加载TOML配置文件
	if err := container.Load("config.toml", confiq.TOML); err != nil {
		fmt.Printf("加载TOML配置失败: %v\n", err)
	}
}

2. 读取配置值

// 读取字符串配置
appName := container.String("app.name", "defaultAppName")

// 读取整数配置
port := container.Int("server.port", 8080)

// 读取布尔值配置
debug := container.Bool("debug", false)

// 读取浮点数配置
timeout := container.Float64("timeout", 3.5)

// 读取嵌套配置
dbConfig := struct {
    Host     string `config:"host"`
    Port     int    `config:"port"`
    Username string `config:"username"`
    Password string `config:"password"`
}{}
if err := container.Unmarshal("database", &dbConfig); err != nil {
    fmt.Printf("解析数据库配置失败: %v\n", err)
}

3. 环境变量覆盖

// 启用环境变量覆盖
container.EnableEnvOverrides("APP")

// 现在可以通过环境变量覆盖配置
// 例如: APP_SERVER_PORT=9090 会覆盖 server.port 配置

高级用法

1. 多文件合并

container := confiq.New()

// 加载默认配置
container.Load("config.default.json", confiq.JSON)

// 加载环境特定配置(如开发环境)
container.Load("config.dev.json", confiq.JSON)

// 后加载的文件会覆盖前面文件的相同配置项

2. 监听配置变化

// 创建支持热加载的配置容器
container := confiq.NewWithWatcher()

// 加载并监听配置文件
if err := container.LoadAndWatch("config.json", confiq.JSON); err != nil {
    fmt.Printf("加载并监听配置失败: %v\n", err)
}

// 注册配置变更回调
container.OnChange(func() {
    fmt.Println("配置已更新,重新加载...")
    // 在这里处理配置变更逻辑
})

3. 自定义配置源

// 实现confiq.ValueSource接口
type MySource struct {
    data map[string]interface{}
}

func (m *MySource) Get() (map[string]interface{}, error) {
    return m.data, nil
}

// 使用自定义配置源
mySource := &MySource{
    data: map[string]interface{}{
        "custom.key": "value",
    },
}
container.AddSource(mySource)

完整示例

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/greaka/confiq"
)

type Config struct {
	App struct {
		Name    string `config:"name"`
		Version string `config:"version"`
	} `config:"app"`
	Server struct {
		Host string `config:"host"`
		Port int    `config:"port"`
	} `config:"server"`
	Database struct {
		DSN string `config:"dsn"`
	} `config:"database"`
	Features struct {
		NewUI bool `config:"new_ui"`
	} `config:"features"`
}

func main() {
	// 初始化配置容器
	container := confiq.New()

	// 加载配置文件
	if err := container.Load("config.yaml", confiq.YAML); err != nil {
		log.Fatalf("加载配置文件失败: %v", err)
	}

	// 启用环境变量覆盖
	container.EnableEnvOverrides("MYAPP")

	// 解析到结构体
	var cfg Config
	if err := container.Unmarshal("", &cfg); err != nil {
		log.Fatalf("解析配置失败: %v", err)
	}

	// 使用配置
	fmt.Printf("应用名称: %s\n", cfg.App.Name)
	fmt.Printf("服务器地址: %s:%d\n", cfg.Server.Host, cfg.Server.Port)
	fmt.Printf("数据库DSN: %s\n", cfg.Database.DSN)

	// 动态获取配置值
	for i := 0; i < 5; i++ {
		debugMode := container.Bool("debug", false)
		fmt.Printf("调试模式: %v\n", debugMode)
		time.Sleep(2 * time.Second)
	}
}

配置文件示例

YAML格式 (config.yaml)

app:
  name: "My Awesome App"
  version: "1.0.0"

server:
  host: "0.0.0.0"
  port: 8080

database:
  dsn: "user:pass@tcp(localhost:3306)/dbname"

features:
  new_ui: true

debug: false

JSON格式 (config.json)

{
  "app": {
    "name": "My Awesome App",
    "version": "1.0.0"
  },
  "server": {
    "host": "0.0.0.0",
    "port": 8080
  },
  "database": {
    "dsn": "user:pass@tcp(localhost:3306)/dbname"
  },
  "features": {
    "new_ui": true
  },
  "debug": false
}

confiq库提供了简单易用的API来处理多种格式的配置文件,支持配置合并、环境变量覆盖和热加载等功能,非常适合在Go项目中使用。

回到顶部