How to get environment variable value with the help of struct tags?

Struct Tags

Go struct tags are annotations that appear after the type in a Go struct declaration. Each tag is composed of short strings associated with some corresponding value.

A struct tag looks like this, with the tag offset with backtick “ characters:

type User struct {
	Name string `example:"name"`
}

We can write other go code to examine the tags and do some cool stuff with it. The tags don’t change the main go struct behavior.

How to get environment variable value by the struct tags?

The classic example of populating the struct fields by the environment variable is by doing os.Getenv() again and again and manually populating the values. But in this case the work is to much repeat and error prone if the struct is too large.

type EmailConfig struct {
	Email string `env:"EMAIL"`
}

func main() {
	cfg := EmailConfig{
		Email: os.Getenv("EMAIL")
	}
}

But can we improve it? Yes we can by using the reflection

import (
	"fmt"
	"os"
	"reflect"
)

type Config struct {
	Email    string `env:"EMAIL"`
}

const tagName = "env"

func LoadConfig(q *Config) {
	v := reflect.ValueOf(q).Elem()
	if v.Kind() == reflect.Struct {
		val := reflect.TypeOf(q).Elem()
		for i := 0; i < val.NumField(); i++ {
			field := val.Field(i)
			tag := field.Tag.Get(tagName)
			fmt.Printf("field : %v | tagName : %v\n", field.Name, tag)
			envVal := os.Getenv(tag)
			reflect.ValueOf(q).Elem().FieldByName(field.Name).Set(reflect.ValueOf(envVal))
		}
	}
}

func main() {
	var cfg Config
	LoadConfig(&cfg)
	fmt.Println(cfg)
}
  • Here we have initiated a empty cfg structs and passed the reference in the LoadConfig function.
  • In the LoadConfig function we have iterated over the struct field.
  • we extract the tag fields and set the field values with the environment variable value extracted by the tag name.
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s