Praktischer Leitfaden zu Umgebungsvariablen in Go

Hallo Habr! Ich präsentiere Ihnen die Übersetzung des Artikels Eine sachliche Anleitung zu Umgebungsvariablen in Go von Enda Phelan.

Umgebungsvariablen sind der beste Weg, um Anwendungskonfigurationen zu speichern, da sie auf Systemebene festgelegt werden können. Dies ist eines der Prinzipien der Twelve-Factor App- Methodik. Sie ermöglicht es Ihnen, Anwendungen von dem System zu trennen, auf dem sie ausgeführt werden (die Konfiguration kann zwischen den Bereitstellungen erheblich variieren, der Code sollte nicht unterschiedlich sein).

Umgebungsvariablen verwenden


Alles, was für die Interaktion mit Umgebungsvariablen benötigt wird, befindet sich in der OS- Standardbibliothek. So erhalten Sie den Wert der Umgebungsvariablen PATH:

package main import ( "fmt" "os" ) func main() { // Store the PATH environment variable in a variable path, exists := os.LookupEnv("PATH") if exists { // Print the value of the environment variable fmt.Print(path) } } 

Und so - setzen Sie den Wert der Variablen:

 package main import ( "fmt" "os" ) func main() { // Set the USERNAME environment variable to "MattDaemon" os.Setenv("USERNAME", "MattDaemon") // Get the USERNAME environment variable username := os.Getenv("USERNAME") // Prints out username environment variable fmt.Print(username) } 

Laden von Umgebungsvariablen aus einer .env-Datei


Auf einer Entwicklungsmaschine, auf der viele Projekte sofort gestartet werden, ist das Speichern von Parametern in variablen Umgebungen nicht immer bequem. Es wäre logischer, sie mithilfe von env-Dateien zwischen Projekten aufzuteilen. Sie können dies beispielsweise mit godotenv tun - dies ist das dotenv, das auf die Go Ruby-Bibliothek portiert ist. Hier können Sie die für die Anwendung erforderlichen Umgebungsvariablen aus der ENV-Datei festlegen.

Führen Sie zum Installieren des Pakets Folgendes aus:

 go get github.com/joho/godotenv 

Fügen Sie die Einstellungen zur .env-Datei im Stammverzeichnis des Projekts hinzu:

 GITHUB_USERNAME=craicoverflow GITHUB_API_KEY=TCtQrZizM1xeo1v92lsVfLOHDsF7TfT5lMvwSno 

Jetzt können Sie diese Werte in der Anwendung verwenden:

 package main import ( "log" "github.com/joho/godotenv" "fmt" "os" ) // init is invoked before main() func init() { // loads values from .env into the system if err := godotenv.Load(); err != nil { log.Print("No .env file found") } } func main() { // Get the GITHUB_USERNAME environment variable githubUsername, exists := os.LookupEnv("GITHUB_USERNAME") if exists { fmt.Println(githubUsername) } // Get the GITHUB_API_KEY environment variable githubAPIKey, exists := os.LookupEnv("GITHUB_API_KEY") if exists { fmt.Println(githubAPIKey) } } 

Es ist wichtig zu beachten, dass Go diesen Wert anstelle des in der env-Datei angegebenen Werts verwendet, wenn der Wert der Umgebungsvariablen auf Systemebene festgelegt wird.

Umgebungsvariablen in das Konfigurationsmodul einschließen


Es ist natürlich schön, wie oben gezeigt direkt auf Umgebungsvariablen zuzugreifen, aber die Aufrechterhaltung einer solchen Lösung scheint ziemlich problematisch. Der Variablenname ist eine Zeichenfolge. Wenn er sich ändert, stellen Sie sich Kopfschmerzen vor, die dazu führen, dass Variablenreferenzen in der gesamten Anwendung aktualisiert werden.

Um dieses Problem zu lösen, erstellen wir ein Konfigurationsmodul für die zentralere und unterstützte Arbeit mit Umgebungsvariablen.

Hier ist ein einfaches Konfigurationsmodul , das Konfigurationsparameter in der Konfigurationsstruktur zurückgibt (wir legen auch die Standardwerte der Parameter fest, falls das System keine Umgebungsvariable enthält):

 package config import ( "os" ) type GitHubConfig struct { Username string APIKey string } type Config struct { GitHub GitHubConfig } // New returns a new Config struct func New() *Config { return &Config{ GitHub: GitHubConfig{ Username: getEnv("GITHUB_USERNAME", ""), APIKey: getEnv("GITHUB_API_KEY", ""), }, } } // Simple helper function to read an environment or return a default value func getEnv(key string, defaultVal string) string { if value, exists := os.LookupEnv(key); exists { return value } return defaultVal } 

Fügen Sie als Nächstes die Typen zur Konfigurationsstruktur hinzu , da die vorhandene Lösung nur Zeichenfolgentypen unterstützt, was für große Anwendungen nicht sehr sinnvoll ist.

Erstellen Sie Handler für die Typen Bool, Slice und Integer:

 package config import ( "os" "strconv" "strings" ) type GitHubConfig struct { Username string APIKey string } type Config struct { GitHub GitHubConfig DebugMode bool UserRoles []string MaxUsers int } // New returns a new Config struct func New() *Config { return &Config{ GitHub: GitHubConfig{ Username: getEnv("GITHUB_USERNAME", ""), APIKey: getEnv("GITHUB_API_KEY", ""), }, DebugMode: getEnvAsBool("DEBUG_MODE", true), UserRoles: getEnvAsSlice("USER_ROLES", []string{"admin"}, ","), MaxUsers: getEnvAsInt("MAX_USERS", 1), } } // Simple helper function to read an environment or return a default value func getEnv(key string, defaultVal string) string { if value, exists := os.LookupEnv(key); exists { return value } return defaultVal } // Simple helper function to read an environment variable into integer or return a default value func getEnvAsInt(name string, defaultVal int) int { valueStr := getEnv(name, "") if value, err := strconv.Atoi(valueStr); err == nil { return value } return defaultVal } // Helper to read an environment variable into a bool or return default value func getEnvAsBool(name string, defaultVal bool) bool { valStr := getEnv(name, "") if val, err := strconv.ParseBool(valStr); err == nil { return val } return defaultVal } // Helper to read an environment variable into a string slice or return default value func getEnvAsSlice(name string, defaultVal []string, sep string) []string { valStr := getEnv(name, "") if valStr == "" { return defaultVal } val := strings.Split(valStr, sep) return val } 

Fügen Sie unserer env-Datei neue Umgebungsvariablen hinzu:

 GITHUB_USERNAME=craicoverflow GITHUB_API_KEY=TCtQrZizM1xeo1v92lsVfLOHDsF7TfT5lMvwSno MAX_USERS=10 USER_ROLES=admin,super_admin,guest DEBUG_MODE=false 

Jetzt können Sie sie überall in der Anwendung verwenden:

 package main import ( "fmt" "log" "github.com/craicoverflow/go-environment-variables-example/config" "github.com/joho/godotenv" ) // init is invoked before main() func init() { // loads values from .env into the system if err := godotenv.Load(); err != nil { log.Print("No .env file found") } } func main() { conf := config.New() // Print out environment variables fmt.Println(conf.GitHub.Username) fmt.Println(conf.GitHub.APIKey) fmt.Println(conf.DebugMode) fmt.Println(conf.MaxUsers) // Print out each role for _, role := range conf.UserRoles { fmt.Println(role) } } 

Fertig!


Ja, es gibt Pakete, die eine schlüsselfertige Lösung für die Konfiguration Ihrer Anwendung bieten. Aber wie viel werden sie benötigt, wenn es so einfach ist, dies selbst zu tun?

Und wie verwalten Sie die Konfiguration in Ihrer Anwendung?

Source: https://habr.com/ru/post/de446468/


All Articles