golang基于结构体标签的命令行、环境变量及JSON/YAML配置解析插件库nfigure的使用

golang基于结构体标签的命令行、环境变量及JSON/YAML配置解析插件库nfigure的使用

nfigure是一个反射式配置库,支持通过结构体标签描述配置项,并从多种来源加载配置:

安装

go get github.com/muir/nfigure

主要特性

  • 使用结构体标签描述配置项
  • 支持多种配置来源:配置文件、环境变量、命令行参数
  • 支持JSON/YAML等多种配置文件格式
  • 支持Posix风格和Go风格命令行参数解析
  • 支持子命令解析
  • 支持自定义类型
  • 支持数组、切片、map和time.Duration等类型

示例代码

在库中使用

type myLibraryConfig struct {
	Field1	string	  `env="FIELD1" flag:"field1" default:"f1" help:"Field1 controls the first field"`
	Field2	int	  `config:"mylibrary.field2"` 
	Field3	[]string  `flag:"field3"`
}

type MyLibrary struct {
	config	myLibraryConfig
}

func createMyLibrary(nreg *nfigure.Registry) *MyLibrary {
	lib := MyLibrary{}
	nreg.Request(&lib.config,
		nfigure.Prefix("myLibrary"),
		nfigure.ConfigFileFrom(`env="MYLIBRARY_CONFIG_FILE" flag:"mylibrary-config"`),
	)
	_ = nreg.Configure()
	return &lib
}

在程序中使用

type programLevelConfig struct {
	Field1	string `env="field1" default:"F1"`
	Field4	float64	`flag:"field4" default:"3.9"`
}

func createMyApp(myLibrary *mylibrary.MyLibrary, nreg *nfigure.Registery) error {
	var config programLevelConfig
	nreg.Request(&config, "main")
	_ = nreg.Configure()
}

func main() {
	app, _ := nserve.CreateApp("myApp", 
		nfigure.NewRegistryFactory(),
		createMyLibrary, 
		createMyApp)
	_ = app.Do(nserve.Start)
	_ = app.Do(nserve.Stop)
}

支持的标签

  • nfigure: 元标签,用于控制填充器交互
  • default: 提供默认值
  • env: 从环境变量填充值
  • config: 从配置文件填充值
  • flag: 从命令行参数填充值
  • help: 命令行帮助文本

环境变量使用

type Config struct {
	Field string `env:"VARNAME"`
}

命令行参数解析

支持Go风格和Posix风格命令行参数解析:

type Config struct {
	// 基本用法
	Field1 string `flag:"field1"`
	
	// 单字母简写
	Field2 string `flag:"field2 f"`
	
	// 数组值,用逗号分隔
	Field3 []string `flag:"field3,split=comma"`
	
	// 数组值,多次指定
	Field4 []string `flag:"field4,explode=true"`
	
	// 计数器
	Field5 int `flag:"field5,counter"`
	
	// map值
	Field6 map[string]string `flag:"field6,map=explode,split=equal"`
}

最佳实践

现有库的适配

package mylibrary 

import (
	"flag"
	"github.com/muir/nfigure"
)

type MyConfig struct {
	MyField string `flag:"myfield"`
}
var myConfig MyConfig

func init() {
	err := nfigure.ExportToFlagSet(flag.CommandLine, "flag", &myConfig)
	if err != nil {
		panic(err.Error())
	}
}

新库的开发

import "github.com/muir/nfigure"

func NewWithRegistry(registry *nfigure.Registry) MySelf {
	var config Config
	registry.Request(&config)
	// ...
}

func NewWithConfig(config *Config) MySelf {
	// ...
}

func (m MySelf) Start() {
	// ...
}

不使用nfigure的程序

import (
	"flag"
	"library"
	"github.com/muir/nfigure"
)

func main() {
	var libConfig library.Config
	nfigure.MustExportToFlagSet(flag.CommandLine, "flag", &libConfig)
	lib := library.NewWithConfig(libConfig)
	flag.Parse()
	lib.Start()
}

使用nfigure的程序

import (
	"flag"
	"library"
	"github.com/muir/nfigure"
)

func main() {
	registry := nfigure.NewRegistry(WithFiller("flag", GoFlagHandler()))
	lib := registry.NewWithRegistry(registry)
	registry.Configure()
	lib.Start()
}

nfigure提供了灵活的配置管理方式,可以方便地在库和应用程序中统一管理各种来源的配置。


更多关于golang基于结构体标签的命令行、环境变量及JSON/YAML配置解析插件库nfigure的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang基于结构体标签的命令行、环境变量及JSON/YAML配置解析插件库nfigure的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用nfigure库解析配置

nfigure是一个强大的Go库,可以帮助你从多个来源(命令行参数、环境变量、JSON/YAML文件)解析配置到结构体中。它利用结构体标签来定义配置来源和解析规则。

基本用法

首先安装nfigure库:

go get github.com/muir/nfigure

定义配置结构

type Config struct {
    Port     int    `env:"PORT" flag:"port" default:"8080" help:"Server port"`
    LogLevel string `env:"LOG_LEVEL" flag:"log-level" default:"info" help:"Log level (debug, info, warn, error)"`
    DBURL    string `env:"DB_URL" flag:"db-url" required:"true" help:"Database connection URL"`
}

标签说明:

  • env: 环境变量名
  • flag: 命令行参数名
  • default: 默认值
  • help: 帮助信息
  • required: 是否必需

解析配置

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/muir/nfigure"
)

func main() {
    var cfg Config
    
    // 创建Registry
    registry := nfigure.NewRegistry()
    
    // 注册配置源
    registry.Register(
        nfigure.Environment(""), // 环境变量
        nfigure.CommandLine(os.Args[1:]), // 命令行参数
        nfigure.ConfigFile("config.yaml", nfigure.Yaml), // YAML配置文件
    )
    
    // 解析配置到结构体
    if err := registry.Parse(&cfg); err != nil {
        log.Fatalf("Failed to parse config: %v", err)
    }
    
    fmt.Printf("Config: %+v\n", cfg)
}

高级特性

嵌套结构体

type DatabaseConfig struct {
    Host     string `env:"DB_HOST" flag:"db-host" default:"localhost"`
    Port     int    `env:"DB_PORT" flag:"db-port" default:"5432"`
    Username string `env:"DB_USER" flag:"db-user" required:"true"`
    Password string `env:"DB_PASS" flag:"db-pass" required:"true"`
}

type AppConfig struct {
    Server struct {
        Port int `env:"PORT" flag:"port" default:"8080"`
    }
    Database DatabaseConfig
}

自定义解析器

type Duration time.Duration

func (d *Duration) Set(value string) error {
    dur, err := time.ParseDuration(value)
    if err != nil {
        return err
    }
    *d = Duration(dur)
    return nil
}

type Config struct {
    Timeout Duration `env:"TIMEOUT" flag:"timeout" default:"5s"`
}

多配置文件支持

registry.Register(
    nfigure.ConfigFile("config.json", nfigure.Json),
    nfigure.ConfigFile("config.yaml", nfigure.Yaml),
    nfigure.ConfigFile("config.toml", nfigure.Toml),
)

最佳实践

  1. 配置优先级:通常命令行参数 > 环境变量 > 配置文件 > 默认值
  2. 敏感信息:不要将密码等敏感信息放在配置文件中,使用环境变量
  3. 配置验证:在Parse后添加验证逻辑
  4. 帮助信息:为重要参数添加help标签
// 添加配置验证
func validateConfig(cfg *Config) error {
    if cfg.Port < 1 || cfg.Port > 65535 {
        return fmt.Errorf("invalid port number: %d", cfg.Port)
    }
    return nil
}

// 在main函数中使用
if err := validateConfig(&cfg); err != nil {
    log.Fatalf("Invalid config: %v", err)
}

nfigure库提供了灵活且强大的配置管理能力,可以大大简化Go应用程序的配置管理。通过结构体标签,你可以清晰地定义配置项的来源和规则,而无需编写大量的解析代码。

回到顶部