ulflow_phattt2901 d4c11c12be <chore>: Update port 3000 & update makefile
Change port and update makefile for Windows
2025-05-21 15:12:24 +07:00

120 lines
3.2 KiB
Go

package config
import (
"fmt"
"os"
"strings"
"github.com/go-playground/validator/v10"
"github.com/spf13/viper"
)
// ConfigLoader định nghĩa interface để load cấu hình
type ConfigLoader interface {
Load() (*Config, error)
}
// ViperConfigLoader triển khai ConfigLoader với Viper
type ViperConfigLoader struct {
configPaths []string
configName string
configType string
envPrefix string
}
// NewConfigLoader tạo ConfigLoader mới với các giá trị mặc định
func NewConfigLoader() ConfigLoader {
return &ViperConfigLoader{
configPaths: []string{"./configs", ".", "./templates"},
configName: "config",
configType: "yaml",
envPrefix: "APP",
}
}
// Load đọc cấu hình từ file và biến môi trường
func (l *ViperConfigLoader) Load() (*Config, error) {
// Khởi tạo viper
v := viper.New()
// Thiết lập tên config và loại
v.SetConfigName(l.configName)
v.SetConfigType(l.configType)
// Thêm các paths để tìm config
for _, path := range l.configPaths {
v.AddConfigPath(path)
}
// Tự động đọc biến môi trường
v.AutomaticEnv()
v.SetEnvPrefix(l.envPrefix)
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
// Thiết lập giá trị mặc định
setDefaultValues(v)
// Đọc cấu hình
if err := v.ReadInConfig(); err != nil {
// Chỉ cảnh báo nếu không tìm thấy file, không gây lỗi
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return nil, fmt.Errorf("error reading config file: %v", err)
}
}
// Set default logger level
if os.Getenv("LOG_LEVEL") == "" {
if err := os.Setenv("LOG_LEVEL", "info"); err != nil {
return nil, fmt.Errorf("failed to set LOG_LEVEL: %v", err)
}
}
// Bind cấu hình vào struct
var config Config
if err := v.Unmarshal(&config); err != nil {
return nil, fmt.Errorf("unable to decode config into struct: %v", err)
}
// Validate cấu hình
if err := validateConfig(&config); err != nil {
return nil, fmt.Errorf("config validation error: %v", err)
}
return &config, nil
}
// setDefaultValues thiết lập các giá trị mặc định cho config
func setDefaultValues(v *viper.Viper) {
// App defaults
v.SetDefault("app.name", "GoStarter")
v.SetDefault("app.version", "0.1.0")
v.SetDefault("app.environment", "development")
v.SetDefault("app.log_level", "info")
v.SetDefault("app.timezone", "UTC")
// Server defaults
v.SetDefault("server.host", "0.0.0.0")
v.SetDefault("server.port", 3000)
v.SetDefault("server.read_timeout", 15) // seconds
v.SetDefault("server.write_timeout", 15) // seconds
v.SetDefault("server.shutdown_timeout", 30) // seconds
v.SetDefault("server.trusted_proxies", []string{})
v.SetDefault("server.allow_origins", []string{"*"})
// Database defaults
v.SetDefault("database.driver", "postgres")
v.SetDefault("database.host", "localhost")
v.SetDefault("database.port", 5432)
v.SetDefault("database.max_open_conns", 25)
v.SetDefault("database.max_idle_conns", 5)
v.SetDefault("database.conn_max_lifetime", 300) // seconds
v.SetDefault("database.ssl_mode", "disable")
v.SetDefault("database.migration_path", "migrations")
}
// validateConfig xác thực cấu hình
func validateConfig(config *Config) error {
validate := validator.New()
return validate.Struct(config)
}