Configuration d'applications en Go (Golang) : des variables d'environnement aux structures YAML complexes
La configuration est l'un des aspects clés de toute application en production. En Go (Golang), l'écosystème propose des outils flexibles et puissants pour gérer les paramètres, adaptés à différents scénarios : des applications 12-factor simples aux microservices avec des dizaines de paramètres. Dans cet article, nous aborderons les approches principales, les bibliothèques populaires et les bonnes pratiques de configuration des applications Go.
Pourquoi une configuration dédiée ?
Le codage en dur des paramètres (hardcode) est un anti-patron. La configuration permet :
- De modifier le comportement de l'application sans recompilation ;
- De séparer les paramètres pour différents environnements (dev/staging/prod) ;
- D'assurer la sécurité (les secrets ne se retrouvent pas dans le dépôt) ;
- De simplifier le déploiement dans les conteneurs et les plateformes cloud.
Approche de base : les variables d'environnement
La bibliothèque standard de Go fournit la fonction os.Getenv. C'est une méthode minimaliste mais efficace pour les petits projets, conforme aux principes de l'application 12-factor.
package main
import ( "fmt" "os")
type Config struct { Port string DBHost string DBUser string}
func loadConfig() Config { return Config{ Port: getEnv("APP_PORT", "8080"), DBHost: getEnv("DB_HOST", "localhost"), DBUser: getEnv("DB_USER", "admin"), }}
func getEnv(key, fallback string) string { if value, ok := os.LookupEnv(key); ok { return value } return fallback}
func main() { cfg := loadConfig() fmt.Printf("Server starting on port %s", cfg.Port)}Bibliothèque Viper : le « couteau suisse » de la configuration
Viper (créé par les auteurs de Cobra) est la bibliothèque de configuration la plus populaire en Go. Elle prend en charge de nombreux formats, la recherche dans plusieurs sources et la hiérarchie des paramètres.
Fonctionnalités principales de Viper :
- Lecture depuis YAML, JSON, TOML, HCL, INI, envfile, Java properties ;
- Prise en charge des variables d'environnement avec des préfixes personnalisés ;
- Définition de valeurs par défaut ;
- Mise à jour dynamique de la configuration (live reload) ;
- Intégration avec des sources distantes (etcd, Consul, Firebase).
Exemple d'utilisation de Viper avec YAML :
package main
import ( "fmt" "github.com/spf13/viper")
type AppConfig struct { Server ServerConfig `mapstructure:"server"` Database DatabaseConfig `mapstructure:"database"`}
type ServerConfig struct { Port int `mapstructure:"port"` Host string `mapstructure:"host"`}
type DatabaseConfig struct { URL string `mapstructure:"url"` Pool int `mapstructure:"pool"`}
func main() { viper.SetConfigName("config") // nom du fichier sans extension viper.SetConfigType("yaml") // format viper.AddConfigPath(".") // chemin de recherche viper.AddConfigPath("./config/")
// Lecture des variables d'environnement avec le préfixe APP_ viper.AutomaticEnv() viper.SetEnvPrefix("APP")
if err := viper.ReadInConfig(); err != nil { panic(fmt.Errorf("fatal error config file: %s", err)) }
var cfg AppConfig if err := viper.Unmarshal(&cfg); err != nil { panic(fmt.Errorf("unable to decode into struct: %s", err)) }
fmt.Printf("Server: %s:%d", cfg.Server.Host, cfg.Server.Port) fmt.Printf("Database URL: %s", cfg.Database.URL)}Exemple de fichier config.yaml :
server: port: 8080 host: "0.0.0.0"database: url: "postgres://user:pass@localhost:5432/app" pool: 10Bibliothèque envconfig : simplicité et déclarativité
Si vous n'avez pas besoin de formats complexes, mais uniquement de variables d'environnement — Aussi dans la bibliothèque
Alembic – migrations de base de données
Générateur de QR codes en TypeScript : la bibliothèque qrcode et son utilisation
Internationalisation (i18n) en PHP : la bibliothèque gettext et les approches modernes
Eigen C++ : guide complet avec exemples pratiques
Travailler avec Kafka en JavaScript (Node.js) : la bibliothèque node-rdkafka
Recommendations