Gu铆a pr谩ctica de variables de entorno en Go

Hola Habr! Le presento la traducci贸n de Una gu铆a sin sentido para las variables de entorno en Go by Enda Phelan.

Las variables de entorno son la mejor manera de almacenar configuraciones de aplicaciones, ya que se pueden configurar a nivel del sistema. Este es uno de los principios de la metodolog铆a de la aplicaci贸n Twelve-Factor , le permite separar las aplicaciones del sistema en el que se est谩n ejecutando (la configuraci贸n puede variar significativamente entre implementaciones, el c贸digo no debe ser diferente).

Usar variables de entorno


Todo lo que se necesita para interactuar con las variables de entorno est谩 en la biblioteca est谩ndar del sistema operativo. As铆 es como obtener el valor de la variable de entorno 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) } } 

Y as铆, establezca el valor de la variable:

 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) } 

Carga de variables de entorno desde un archivo .env


En una m谩quina de desarrollo, donde muchos proyectos se inician de inmediato, el almacenamiento de par谩metros en entornos variables no siempre es conveniente; Ser铆a m谩s l贸gico dividirlos entre proyectos utilizando archivos env. Puede hacer esto, por ejemplo, usando godotenv : este es el dotenv portado a la biblioteca Go Ruby. Le permite establecer las variables de entorno necesarias para la aplicaci贸n desde el archivo .env.

Para instalar el paquete, ejecute:

 go get github.com/joho/godotenv 

Agregue la configuraci贸n al archivo .env en la ra铆z del proyecto:

 GITHUB_USERNAME=craicoverflow GITHUB_API_KEY=TCtQrZizM1xeo1v92lsVfLOHDsF7TfT5lMvwSno 

Ahora puede usar estos valores en la aplicaci贸n:

 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 importante recordar que si el valor de la variable de entorno se establece en el nivel del sistema, Go usar谩 este valor en lugar del especificado en el archivo env.

Ajustar variables de entorno en el m贸dulo de configuraci贸n


Es agradable, por supuesto, tener acceso a las variables de entorno directamente, como se muestra arriba, pero mantener una soluci贸n as铆 parece bastante problem谩tico. El nombre de la variable es una cadena y, si cambia, imagine un dolor de cabeza que dar谩 como resultado el proceso de actualizaci贸n de referencias de variables en toda la aplicaci贸n.

Para resolver este problema, crearemos un m贸dulo de configuraci贸n para trabajar con variables de entorno de una manera m谩s centralizada y compatible.

Aqu铆 hay un m贸dulo de configuraci贸n simple que devuelve los par谩metros de configuraci贸n en la estructura de configuraci贸n (tambi茅n establecemos los valores predeterminados de los par谩metros en caso de que no haya una variable de entorno en el sistema):

 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 } 

A continuaci贸n, agregue los tipos a la estructura Config , ya que la soluci贸n existente solo admite tipos de cadenas, lo que no es muy razonable para aplicaciones grandes.

Cree controladores para los tipos bool, slice y entero:

 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 } 

Agregue nuevas variables de entorno a nuestro archivo env:

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

Ahora puede usarlos en cualquier lugar de la aplicaci贸n:

 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) } } 

Hecho


S铆, hay paquetes que ofrecen una soluci贸n llave en mano para configurar su aplicaci贸n, pero 驴cu谩nto se necesitan si es tan f谩cil hacerlo usted mismo?

驴Y c贸mo gestiona la configuraci贸n en su aplicaci贸n?

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


All Articles