Высвобождение силы Viper

Введение

Вы когда-нибудь работали в службе, которая требует множества настроек, таких как конечные точки API, секретные значения, язык и другие конфигурации? Если да, то вы знаете, насколько сложно управлять ими всеми без надлежащей системы. К счастью, у Go есть отличный пакет, который поможет вам беспрепятственно управлять своими конфигурациями.

Viper — это мощная и настраиваемая библиотека для управления конфигурацией приложений в Go. Viper является гибким, простым в использовании и простым в настройке и управлении конфигурацией в ваших приложениях Go. Это позволяет инженерам работать с несколькими источниками конфигурации, включая файлы, переменные среды, флаги командной строки и удаленные хранилища ключей и значений.

В этом сообщении блога мы углубимся в детали Viper, изучим его функции и предоставим примеры того, как использовать его в ваших проектах. К концу вы будете готовы использовать Viper в своих приложениях Go.

Viper был разработан с учетом принципов 12-факторного приложения с целью создать для инженеров беспроблемный опыт работы с данными конфигурации.

Некоторые ключевые особенности Viper включают

  • Поддержка нескольких форматов файлов конфигурации (JSON, TOML, YAML, HCL, INI и др.)
  • Автоматическая привязка переменных среды и флагов командной строки
  • Поддержка удаленных хранилищ ключей и значений, таких как etcd или Consul.
  • Обнаружение изменений в режиме реального времени и оперативные обновления конфигурации
  • Значения по умолчанию и десортировка в пользовательские структуры

Установка и настройка

Чтобы начать работу с Viper, вам сначала необходимо установить пакет с помощью следующей команды:

go get github.com/spf13/viper

Затем импортируйте пакет Viper в свой код Go:

import "github.com/spf13/viper"

Работа с файлами конфигурации

Viper поддерживает несколько форматов файлов конфигурации, включая JSON, TOML, YAML, HCL и INI.

Пример конфигурации. файл yaml

# 
server:
  port: 8080
  host: localhost
database:
  driver: mysql
  host: localhost
  port: 3306
  name: mydb
  user: myuser
  password: mypass

Чтобы прочитать файл конфигурации, вы должны задать имя, формат и местоположение файла.

viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/app/")
viper.AddConfigPath("$HOME/.app")
viper.AddConfigPath(".")

В этом примере Viper ищет файл с именем Config.yaml in /etc/app/ ,$HOME/.appи основной каталог вашего проекта. Чтобы прочитать файл конфигурации, вызовите функцию ReadInConfig():

err := viper.ReadInConfig()
if err != nil {
    log.Fatalf("Error reading config file: %s", err)
}

Теперь вы можете получить доступ к значениям в файле конфигурации с помощью Get() или методов определенного типа, таких как GetString(), GetInt() и GetBool().

port := viper.GetInt("server.port")

Переменные среды и флаги командной строки

Viper может автоматически привязывать переменные среды и флаги командной строки к вашим конфигурационным ключам. Для этого используйте функцию AutomaticEnv() и определите привязки флагов.

viper.AutomaticEnv()

flag.Int("port", 8080, "Port to run the server on")
flag.Parse()

viper.BindPFlag("server.port", flag.Lookup("port"))

Теперь, если вы установите переменную среды или передадите флаг командной строки, Viper будет использовать предоставленное значение вместо значения из файла конфигурации.

Удаленные хранилища ключей и значений

Viper также поддерживает удаленные хранилища ключей и значений, такие как etcd или Consul. Чтобы использовать удаленное хранилище, импортируйте соответствующий пакет удаленного поставщика и настройте информацию о соединении. Вот пример использования etcd:

Сначала установите удаленный провайдер etcd Viper:

go get github.com/spf13/viper/remote

Импортируйте необходимые пакеты в свой код Go:

import (
    "github.com/spf13/viper"
    "github.com/spf13/viper/remote"
)

Настройте Viper для использования провайдера etcd:

const etcdConfigKey = "/config/myapp"

err := viper.AddRemoteProvider("etcd", "http://127.0.0.1:2379", etcdConfigKey)
if err != nil {
    log.Fatalf("Unable to add remote provider: %s", err)
}

viper.SetConfigType("yaml")
err = viper.ReadRemoteConfig()
if err != nil {
    log.Fatalf("Error reading remote config: %s", err)
}

Теперь Viper прочитает данные конфигурации, хранящиеся под ключом /config/myapp на сервере etcd.

Значения по умолчанию и демаршаллинг

Viper позволяет установить значения по умолчанию для ключей конфигурации. Это полезно при предоставлении разумных значений по умолчанию для вашего приложения, даже если файл конфигурации или переменные среды не установлены.

viper.SetDefault("server.port", 8080)

Viper также может преобразовать данные конфигурации в пользовательскую структуру. Это упрощает работу с данными конфигурации в вашем приложении, поскольку вы можете получить к ним доступ, используя определенную структуру. Вот пример:

type Config struct {
    Server struct {
        Port int
    }
}

var config Config
err := viper.Unmarshal(&config)
if err != nil {
    log.Fatalf("Error unmarshalling config: %s", err)
}

port := config.Server.Port

Наблюдая за изменениями

Одной из мощных функций Viper является его способность отслеживать изменения конфигурации и обновлять значения в режиме реального времени. Чтобы включить эту функцию, вызовите функцию WatchConfig() и зарегистрируйте функцию обратного вызова для обработки изменений.

viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
    log.Printf("Config file changed: %s", e.Name)
    // Reload your configuration or perform any necessary actions here
})

Viper автоматически обновит значения при изменении файла конфигурации и вызовет зарегистрированную функцию обратного вызова.