دليل عملي لمتغيرات البيئة في الذهاب

مرحبا يا هبر! أقدم لكم ترجمة المقال دليل لا معنى له لمتغيرات البيئة في Go by Enda Endelan.

تعد متغيرات البيئة هي أفضل طريقة لتخزين تكوينات التطبيقات ، حيث يمكن ضبطها على مستوى النظام. هذا أحد مبادئ منهجية تطبيق Twelve-Factor App ، فهو يسمح لك بفصل التطبيقات عن النظام الذي تعمل فيه (يمكن أن يختلف التكوين بشكل كبير بين عمليات النشر ، ويجب ألا يكون الرمز مختلفًا).

باستخدام متغيرات البيئة


كل ما هو مطلوب للتفاعل مع متغيرات البيئة هو في مكتبة os القياسية. هذه هي كيفية الحصول على قيمة متغير بيئة 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) } } 

وهكذا - اضبط قيمة المتغير:

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

تحميل متغيرات البيئة من ملف .env


على جهاز التطوير ، حيث يتم إطلاق العديد من المشاريع على الفور ، فإن تخزين المعلمات في بيئات متغيرة ليس دائمًا مناسبًا ؛ سيكون من المنطقي تقسيمها بين المشاريع باستخدام ملفات env. يمكنك القيام بذلك ، على سبيل المثال ، باستخدام godotenv - هذا هو dotenv المنقول إلى مكتبة Go Ruby. يسمح لك بتعيين متغيرات البيئة الضرورية للتطبيق من ملف .env.

لتثبيت الحزمة ، قم بتشغيل:

 go get github.com/joho/godotenv 

أضف الإعدادات إلى ملف .env في جذر المشروع:

 GITHUB_USERNAME=craicoverflow GITHUB_API_KEY=TCtQrZizM1xeo1v92lsVfLOHDsF7TfT5lMvwSno 

يمكنك الآن استخدام هذه القيم في التطبيق:

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

من المهم أن تتذكر أنه إذا تم تعيين قيمة متغير البيئة على مستوى النظام ، فسيستخدم Go هذه القيمة بدلاً من القيمة المحددة في ملف env.

التفاف متغيرات البيئة في وحدة التكوين


من الجيد ، بالطبع ، الوصول إلى متغيرات البيئة مباشرةً ، كما هو موضح أعلاه ، ولكن الحفاظ على هذا الحل يبدو مشكلة إلى حد ما. اسم المتغير عبارة عن سلسلة ، وإذا تغير ، تخيل صداعًا سينتج عنه عملية تحديث مراجع المتغيرات في جميع أنحاء التطبيق.

لحل هذه المشكلة ، سنقوم بإنشاء وحدة تكوين للعمل مع متغيرات البيئة بطريقة أكثر مركزية ودعمًا.

فيما يلي وحدة تهيئة بسيطة تقوم بإرجاع معلمات التكوين في بنية التكوين (نقوم أيضًا بتعيين القيم الافتراضية للمعلمات في حالة عدم وجود متغير بيئة في النظام):

 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 } 

بعد ذلك ، أضف الأنواع إلى بنية Config ، حيث أن الحل الحالي يدعم فقط أنواع السلسلة ، وهو أمر غير معقول للتطبيقات الكبيرة.

إنشاء معالجات لأنواع bool و slice و 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 } 

أضف متغيرات بيئة جديدة إلى ملف env لدينا:

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

الآن يمكنك استخدامها في أي مكان في التطبيق:

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

القيام به!


نعم ، هناك حزم تقدم حلاً جاهزًا لتكوين التطبيق الخاص بك ، ولكن ما مقدار ما يحتاجون إليه إذا كان من السهل القيام بذلك بنفسك؟

وكيف تدير التكوين في تطبيقك؟

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


All Articles