viper — самая частая рекомендация для конфигурации в Go. Он умеет читать файлы, переменные окружения, удалённые источники и устанавливать дефолты. Звучит удобно, но на практике создаёт проблемы.
🔴 В чём проблема
Viper тянет большое дерево зависимостей. Методы GetString, GetInt и подобные не типизированы — значения возвращаются в рантайме без проверки на этапе компиляции. Ключи конфига разбросаны по коду как строковые литералы. При нетривиальном использовании поведение при слиянии и приоритетах конфигов требует чтения исходников.
🔴 Что использовать
Структура с тегами и yaml.NewDecoder:
type Config struct {
DatabaseURL string `yaml:"database_url"`
Kafka KafkaConfig `yaml:"kafka"`
Server ServerConfig `yaml:"server"`
}
func Load(path string) (*Config, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
var cfg Config
if err := yaml.NewDecoder(f).Decode(&cfg); err != nil {
return nil, err
}
return &cfg, nil
}
Переменные окружения добавляются вручную через os.Getenv там, где это нужно.
🔴 Что получаем
Полностью типизированный конфиг. Никаких строковых ключей. Граф зависимостей, который можно проверить за секунды. Код, который вы полностью контролируете.
Для JSON-конфига подход тот же, только с encoding/json. Пакет
gopkg.in/yaml.v3 — единственная внешняя зависимость, и та минимальная.📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction