บันทึกการเรียน Golang วันที่ 4 - ว่าด้วยเรื่องของ environment variables
วันนี้ได้เรียนรู้และรู้จักกับ Environment Variables ใน Go ว่ามีวิธีการเข้าถึงพวก variables ยังไงได้บ้าง ปกติเวลาที่เขียน Node.js ถ้าไม่ได้กำหนด system variables ก็มักจะใส่ไปพร้อมกับตอน execute command และอีกวิธีคือ ใช้ไฟล์ .env
ร่วมกับ 3rd party library อย่าง dotenv นั่นเอง
สำหรับการฝึกเขียน Golang วันนี้ได้ลองเรียก HTTP Request ผ่านตัว Golang และมีการใช้ credentials ทำให้เราไม่ควรใส่ค่าไว้ใน Source Code ก็เลยมาลองดูว่า มีวิธีไหนบ้าง ที่จะทำงานคล้ายๆ กับ .env
ของ Node.js + dotenv
ลองสร้างโปรเจ็คขึ้นมา และ initial module
mkdir learn-go-day-4
cd learn-go-day-4
go mod init goenv
แบบที่ 1 - Go os.Getenv
วิธีแรก คือใช้ os
ที่เป็น standard library ครับ สร้างไฟล์ขึ้นมาง่ายๆ main.go
package main
import (
"fmt"
"os"
)
func main() {
environment := os.Getenv("GO_ENV")
fmt.Println("GO_ENV: ", environment)
}
เวลารัน command ก็ใส่ env ไปพร้อมๆกัน แบบเดียวกับรัน Node.js
GO_ENV=staging go run go-get.go
// ผลลัพธ์
// GO_ENV: staging
วิธีที่ 2 - ใช้ godotenv
วิธีนี้จะใช้ library ชื่อ godotenv ครับ การใช้งานก็เหมือนกับตัว dotenv ที่เป็นเวอร์ชั่น Node.js คือโหลดจากไฟล์ .env
ซึ่งจริงๆ เราสามารถตั้งชื่ออะไรก็ได้ รวมถึงรองรับ format YAML ด้วยเช่นกัน
ทำการเพิ่ม library
go get github.com/joho/godotenv
สร้างไฟล์ .env
ไว้ที่ root ของโปรเจ็ค ข้างในสมมติ ผมมีแบบนี้อยู่
SECRET_KEY=this_is_super_secret
GO_ENV=development
ขั้นแรก ทำการโหลดไฟล์ .env
ขึ้นมาก่อน
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading env")
}
โดยถ้าใครอยากให้มันโหลดไฟล์ นอกเหนือจาก `.env ก็ระบุชื่อไฟล์ไปเลย เช่น
godotenv.Load("myEnvFile")
ซึ่งเราให้มัน autoload ได้ด้วยแบบนี้ ด้านบนลบทิ้งได้เลย สำหรับสายขี้เกียจ และไฟล์ default ก็เป็นชื่อ .env
อยู่แล้ว ใช้แบบนี้แทนได้
import _ "github.com/joho/godotenv/autoload"
ส่วนนี้ จริงๆ มันก็เหมือนกับเรา โหลด variables ไปพร้อมกับ run คำสั่ง ซึ่งมันมีค่าเท่ากับ
SECRET_KEY=xxx GO_ENV=xxx go run <filename>
ส่วน function ที่ใช้ในการ get env ก็ใช้ตัว standard library ได้เลย
environment := os.Getenv("GO_ENV")
secretKey := os.Getenv("SECRET_KEY")
fmt.Println("GO_ENV: ", environment)
fmt.Println("SECRET_KEY: ", secretKey)
ส่วนการโหลดไฟล์ YAML ก็ทำได้เช่นกัน (แต่ผมยังติดปัญหา ว่ามันไม่สามารถ parse กรณีที่เราใช้เป็น Nested Object หรือเป็น list items แฮะ)
ส่วนอีก library ที่เห็นว่าคนใช้เยอะ ก็คือ Viper ส่วนตัวยังไม่ได้ลองใช้งานนะครับ เพราะตอนนี้ใช้ godotenv ก็ตอบโจทย์ที่โหลด environment variables พวก api key, secret key แล้ว ยังไม่ได้ทำ config ให้มี structure ที่ซับซ้อน ก็เลยยังไม่ได้ใช้ Viper ครับ
ซึ่งจากที่ดูใน Github ตัว Viper รองรับทั้ง .env ทั้ง YAML / JSON และไฟล์หลากหลาย แต่ผมเห็นตัวอย่างโค๊ดแล้ว มันดูจะเยอะเกินไป เหมาะกับโปรเจ็ค หรือ config ไฟล์ที่ซ้ำซ้อนมากกว่า
Happy Coding ❤️