1% 이해하기 시리즈/Golang

[golang 1% 이해하기] viper | dotenv 환경 변수값을 읽는 기능 도입 하기 #2 mapstructure 를 사용해 Env 구조체 할당하기

TLOWAC 2024. 11. 10. 00:03

 

🏃🏻 들어가며

이번글에서는 지난번 글의 연장선으로 viper 에서 mapstructure 를 활용해 환경 변수 값을 활용하는 방법을 정리하였습니다.

 

https://helicopter55.tistory.com/94

 

[golang 1% 이해하기] viper | dotenv 환경 변수값을 읽는 기능 도입 하기 #1 Config 전역 변수를 활용하기

🏃🏻 들어가며이번 글에서는 viper 를 사용해서 dotenv 에 정의된 환경 변수를 읽어오는 방법에 대해서 정리해 보았습니다. godotenv 라이브러리를 사용하는 방식과 mapstructure 를 사용해 Env 구조체(s

helicopter55.tistory.com

 

 

 


 

  Viper 설치 및 mapstructure 를 사용해 Env 구조체 할당하기

1) viper 설치하기

go get 명령어를 통해 viper 라이브러리를 다운로드 받습니다.

 

 go get github.com/spf13/viper 

go get github.com/spf13/viper

 

2) Env struct 생성하기

LoadEnvConfiguration() 이후에 env.AppEnv, env.DBHost, env.DBPort 와 방식으로 사용하기 위해 Env struct 를 mapstructure 을 사용해 작성 합니다. .env 파일에 작성된 DB_PORT 환경 변수값은 Env 구조체의 DBPort 에 맵핑 됩니다.

 

 

mapstructure    |  map[string]interface{}로 표현된 설정 값을 사용자가 정의한 구조체로 손쉽게 매핑할 수 있도록 해줍니다.

type Env struct {
	AppEnv                 string `mapstructure:"APP_ENV"`
	ServerAddress          string `mapstructure:"SERVER_ADDRESS"`
	ContextTimeout         int    `mapstructure:"CONTEXT_TIMEOUT"`
	DBHost                 string `mapstructure:"DB_HOST"`
	DBPort                 string `mapstructure:"DB_PORT"`
	DBUser                 string `mapstructure:"DB_USER"`
	DBPass                 string `mapstructure:"DB_PASS"`
	DBName                 string `mapstructure:"DB_NAME"`
	AccessTokenExpiryHour  int    `mapstructure:"ACCESS_TOKEN_EXPIRY_HOUR"`
	RefreshTokenExpiryHour int    `mapstructure:"REFRESH_TOKEN_EXPIRY_HOUR"`
	AccessTokenSecret      string `mapstructure:"ACCESS_TOKEN_SECRET"`
	RefreshTokenSecret     string `mapstructure:"REFRESH_TOKEN_SECRET"`
}

 

3) LoadEnvConfiguration 제작하기

viper 를 통해 .env 파일에서 환경 변수 값을 가져오고 mapstructure 을 사용해 Env 구조체에 맵핑 하기 위해  LoadEnvConfiguration 함수를 제작 합니다.

 

이렇게 불러온 .env 파일의 환경 변수 값은 main 에서 env.DBName 과 같은 방식으로 호출 하여 사용 할 수 있습니다.

package main

import (
	"fmt"
	"log"

	"github.com/spf13/viper"
)

func main() {

	env := LoadEnvConfiguration()
	dbName := env.DBName
	fmt.Println("dbName", dbName)

	secret := env.AccessTokenSecret
	fmt.Println("secret", secret)
}

type Env struct {
	AppEnv                 string `mapstructure:"APP_ENV"`
	ServerAddress          string `mapstructure:"SERVER_ADDRESS"`
	ContextTimeout         int    `mapstructure:"CONTEXT_TIMEOUT"`
	DBHost                 string `mapstructure:"DB_HOST"`
	DBPort                 string `mapstructure:"DB_PORT"`
	DBUser                 string `mapstructure:"DB_USER"`
	DBPass                 string `mapstructure:"DB_PASS"`
	DBName                 string `mapstructure:"DB_NAME"`
	AccessTokenExpiryHour  int    `mapstructure:"ACCESS_TOKEN_EXPIRY_HOUR"`
	RefreshTokenExpiryHour int    `mapstructure:"REFRESH_TOKEN_EXPIRY_HOUR"`
	AccessTokenSecret      string `mapstructure:"ACCESS_TOKEN_SECRET"`
	RefreshTokenSecret     string `mapstructure:"REFRESH_TOKEN_SECRET"`
}

func LoadEnvConfiguration() *Env {
	env := Env{}
	viper.SetConfigFile("config.env")

	err := viper.ReadInConfig()
	if err != nil {
		log.Fatal("Can't find the file .env : ", err)
	}

	err = viper.Unmarshal(&env)
	if err != nil {
		log.Fatal("Environment can't be loaded: ", err)
	}

	if env.AppEnv == "development" {
		log.Println("The App is running in development env")
	}

	return &env
}

 


 

✴️  아쉬운점

처음에는 Env 구조체의 필드에 ServerConfig, DBConfig 와 같은 구조체를 만들어 사용할려고 했었다.

node.js 에서는 이런 방식으로 많이 사용했었기에 이런 방법을 찾아보고 있었다. 

 

하지만, 아직은 숙련도가 부족한 탓인지 .env 환경 변수값을 가져온 케이스를 작성하지 못했다.

추후에 방법을 알게 되면 링크를 여기에 추가해놓겠습니다 :(

 

아래는 제가 처음에 의도했던 코드 입니다.

type Env struct {
	ServerConfig ServerConfig
	DBConfig DBConfig
}

type ServerConfig struct {
	AppEnv			string `mapstructure:"APP_ENV"`
	Address			string `mapstructure:"SERVER_ADDRESS"`
}

type DBConfig struct {
	Host                 string `mapstructure:"DB_HOST"`
	Port                 string `mapstructure:"DB_PORT"`
	User                 string `mapstructure:"DB_USER"`
	Pass                 string `mapstructure:"DB_PASS"`
	Name                 string `mapstructure:"DB_NAME"`
}

 


 

 

📍마무리하며

이번 글을 통해서 viper 를 활용해 .env 파일의 환경 변수 값을 가져와 mapstructure 를 사용해 Env 구조체 할당하는데 도움이 되었으면 좋겠습니다 :)

실제 동작하는 코드는 여기서 확인 하실 수 있습니다.

반응형