fix(config): fix configuration management
This commit is contained in:
@@ -2,66 +2,67 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// Config holds all configuration for the application.
|
||||
// Config représente la structure globale de la configuration de l'application.
|
||||
type Config struct {
|
||||
Database DatabaseConfig `mapstructure:"database"`
|
||||
Server ServerConfig `mapstructure:"server"`
|
||||
Server ServerConfig
|
||||
Database DatabaseConfig
|
||||
}
|
||||
|
||||
// DatabaseConfig holds database connection configuration.
|
||||
// ServerConfig contient les paramètres de configuration du serveur HTTP.
|
||||
type ServerConfig struct {
|
||||
Address string `mapstructure:"address"`
|
||||
TrustedProxies []string `mapstructure:"trusted_proxies"` // Liste des IPs de proxies de confiance
|
||||
}
|
||||
|
||||
// DatabaseConfig contient les paramètres de configuration de la base de données.
|
||||
type DatabaseConfig struct {
|
||||
User string `mapstructure:"user"`
|
||||
Password string `mapstructure:"password"`
|
||||
Dbname string `mapstructure:"dbname"`
|
||||
Host string `mapstructure:"host"`
|
||||
Port int `mapstructure:"port"`
|
||||
Sslmode string `mapstructure:"sslmode"`
|
||||
User string `mapstructure:"user"`
|
||||
Password string `mapstructure:"password"`
|
||||
DBName string `mapstructure:"dbname"`
|
||||
SSLMode string `mapstructure:"sslmode"`
|
||||
}
|
||||
|
||||
// ServerConfig holds server-specific configuration.
|
||||
type ServerConfig struct {
|
||||
Address string `mapstructure:"address"`
|
||||
}
|
||||
|
||||
// Load reads configuration from file and environment variables.
|
||||
func Load() (*Config, error) {
|
||||
// 0. Configuration for environment variables
|
||||
viper.SetEnvPrefix("APP") // Variables must start with "APP_" (e.g., APP_SERVER_ADDRESS)
|
||||
|
||||
// 1. Base configuration file
|
||||
viper.SetConfigName("config") // config.yaml
|
||||
// LoadConfig charge la configuration depuis un fichier et les variables d'environnement.
|
||||
func LoadConfig(path string) (config Config, err error) {
|
||||
viper.AddConfigPath(path)
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("yaml")
|
||||
viper.AddConfigPath(".")
|
||||
|
||||
// Read the base file. Don't stop if it's not found.
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
viper.SetDefault("server.address", ":8080")
|
||||
viper.SetDefault("server.trusted_proxies", "127.0.0.1, ::1")
|
||||
viper.SetDefault("database.host", "localhost")
|
||||
viper.SetDefault("database.port", 5432)
|
||||
viper.SetDefault("database.user", "default_user")
|
||||
viper.SetDefault("database.password", "")
|
||||
viper.SetDefault("database.dbname", "default_db")
|
||||
viper.SetDefault("database.sslmode", "disable")
|
||||
|
||||
// L'ordre ici est important
|
||||
|
||||
// 1. D'abord, on lit le fichier
|
||||
err = viper.ReadInConfig()
|
||||
if err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
||||
return nil, fmt.Errorf("error reading base config file config.yaml: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Override with environment-specific file (via APP_ENV)
|
||||
if env := os.Getenv("APP_ENV"); env != "" {
|
||||
viper.SetConfigName("config." + env) // e.g., config.prod.yaml
|
||||
if err := viper.MergeInConfig(); err != nil {
|
||||
log.Printf("Warning: could not load config file for environment '%s': %v", env, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Ensuite, on prépare Viper à lire les variables d'environnement
|
||||
viper.SetEnvPrefix("APP")
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
viper.AutomaticEnv()
|
||||
viper.AutomaticEnv() // Dit à Viper de chercher les variables d'environnement
|
||||
|
||||
var cfg Config
|
||||
if err := viper.Unmarshal(&cfg); err != nil {
|
||||
return nil, fmt.Errorf("unable to decode config into struct: %w", err)
|
||||
}
|
||||
// 3. Enfin, on déverse le résultat final dans la struct.
|
||||
// C'est à ce moment que la surcharge a lieu.
|
||||
fmt.Printf("[%v]\n", config.Database.DBName)
|
||||
|
||||
return &cfg, nil
|
||||
err = viper.Unmarshal(&config)
|
||||
return
|
||||
}
|
||||
|
@@ -16,8 +16,8 @@ type Service struct {
|
||||
// NewService initializes and returns a new database service.
|
||||
func NewService(cfg *config.DatabaseConfig) (*Service, error) {
|
||||
connStr := fmt.Sprintf("user=%s password=%s dbname=%s host=%s port=%d sslmode=%s",
|
||||
cfg.User, cfg.Password, cfg.Dbname,
|
||||
cfg.Host, cfg.Port, cfg.Sslmode,
|
||||
cfg.User, cfg.Password, cfg.DBName,
|
||||
cfg.Host, cfg.Port, cfg.SSLMode,
|
||||
)
|
||||
|
||||
db, err := sql.Open("postgres", connStr)
|
||||
|
Reference in New Issue
Block a user