.env
檔案放置的都是 資料庫密碼, API 金鑰 等等不應該外洩的內容,
務必務必要保證不要被提交到 git 或任何一種版本控制管理系統
務必將 .env 檔案加入到 .gitignore 中
在應用程式開發中,設定管理是一個重要的環節。
良好的設定管理能夠讓應用程式在不同環境(如開發、測試、生產)下靈活運行,
同時也能確保敏感資訊(如資料庫密碼、API 金鑰)不會被 寫在 程式碼中。
在 Go 語言裡面,獲取環境變數是一個簡單的動作
environment := os.Getenv("ENVIRONMENT")
那為什麼不要直接使用 os.Getenv() 就好呢,
因為這種做法在大型應用程式中可能會導致一些問題:
重複代碼:每次需要獲取環境變數時,都必須寫一遍 os.Getenv()
,這會導致代碼重複,增加維護成本。
錯誤處理:os.Getenv()
只會返回一個字串,如果環境變數不存在,則返回空字串。這使得錯誤處理變得困難,開發者需要額外的邏輯來處理缺失的環境變數。
測試困難:在單元測試中,模擬環境變數的存在與否變得更加複雜,這可能會導致測試不穩定。
為了解決這些問題,我們可以使用集中式的配置管理工具,來統一管理應用程式的配置。這樣不僅可以減少重複代碼,還能提供更好的錯誤處理和測試支持。
config_types.go
)在 internal/config/config_types.go
中定義我們的 config 會有哪些內容:
// internal/config/config_type.go
type Config struct {
Server ServerConfig
MySQL DatabaseConfig
Redis RedisConfig
Logger LoggerConfig
Token TokenConfig
APIDocAuth APIDocAuth
}
type ServerConfig struct {
Environment string
Port string
}
....
config.go
)internal/config/config.go
中實作載入的 function
這裡會讀取 .env 跟讀取環境變數
// internal/config/config.go
func LoadConfig() (*Config, error) {
v := viper.New()
// 啟用自動讀取環境變數, 用於 Server 部署
v.AutomaticEnv()
// 設定讀取 .env 檔案,用於本地開發使用
v.SetConfigName(".env")
v.SetConfigType("env")
v.AddConfigPath(".")
err := v.ReadInConfig()
if err != nil {
// 如果錯誤是指定的 config 檔案不存在,則不處理
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return nil, fmt.Errorf("error reading config file: %w", err)
}
}
var cfg Config
cfg.Server.Environment = v.GetString("SERVER_ENVIRONMENT")
cfg.Server.Port = v.GetString("SERVER_PORT")
....
return &cfg, nil
}
到這裡看起來,會覺得 os.Getenv() 跟 viper.GetString()
沒什麼差異
但實際上,viper.GetString() 會先查詢已載入的設定檔(如 .env),再查詢環境變數。
這樣就達到,有環境變數,就使用環境變數,否則有給 .env 就使用 .env 的內容
這時候,不論是在 server,還是在本地開發,都不用調整程式碼
.env
檔案與環境變數?同時支援 .env
檔案與環境變數能夠兼顧開發與部署的需求:
.env
檔案可以讓每位開發者根據自身環境快速調整設定,且不必將敏感資訊提交到版本控制。我們已經實現了讀取 .env 跟環境變數
接下來我們就實現 main.go
讓專案可以運行起來
// cmd/api/main.go
func main() {
config, err := config.LoadConfig()
if err != nil {
log.Fatalf("failed to load config: %v", err)
}
// 這裡先只把 config 印出,後續會使用到
log.Println(config)
}
gogogo
go run ./cmd/api/main.go
🎉🎉🎉🎉🎉
在本篇文章中,我們探討了 Go 語言中的設定管理問題,並介紹了 Viper 作為解決方案。透過 Viper,
我們能夠輕鬆地管理應用程式的配置,並在不同環境中保持一致性。
最終,我們實現了一個靈活的設定管理模組,能夠支援 .env 檔案與環境變數的雙重來源,提升了應用程式的可維護性與安全性。
===
以上程式碼的完整內容可以到 Github 觀看