Library to parse env into a struct
It supports all basic parsing of environment variables into the struct object given. An example of it's usage is that you would pass in the following struct:
type MyStruct struct {
Field string `tag:"field"`
}
envstruct
will then fetch the environment variable FIELD
, parse it and set it
back into your struct. So if you had FIELD=foo
set as an envionment variable,
the result will be:
MyStruct{
Field: "foo"
}
I started this project in order to satisfy my use case of being able to use a library that will parse environment variables into a struct using tag values, including the tag values of nested structs. There are a lot of libraries out there that can parse environment variables into structs, but the environment variable that it fetches was built up either using the field names or field tag values that don't include tag values on nested structs.
For example, it supports the following struct:
type MyStruct struct {
Nested struct {
Field string `tag:"field"`
} `tag:"nested"`
}
Which the Field
value will be fetched using NESTED_FIELD
as the string to
fetch the environment variable.
You can use envstruct
by first configuring a few settings.
Settings | Desciptions |
---|---|
Prefix | Optional and if set, is used as the prefix to any environment variable fetching. For example, if we are fetching env string FIELD1 and we have prefix set to BAR , then BAR_FIELD1 will be used to fetch the environment variable. |
TagName | Used for fetching the tag value from the field. A built up string using this tag value will be used to fetch the environment variable. Can be placed on a struct or field. |
Delimiter | Used as the separater for multiple values within a struct or map. It is defaulted to a comma , . It is used so that in the environment variable, there can exist slices such as PREFIX_FIELD=foo,bar . |
Unmarshaler | Used to unmarshal the string into the field types. For example, you can pass in a yaml or json unmarshaler. |
OverrideName | Optional and if set, is used to fetch the tag value from the field that will be used to fetch the environment variable. It is used to override the string built using the TagName . The tag value from OverrideName will be used directly and will not be modified with upper casing, prefixing or attaching nested struct tag values. |
IgnoreTagName | Optional and if set, will be used to recognize when a tag should not be included in the built up string for fetching the environment value. |
StripValue | Optional and if set true, envstruct will remove all characters including and after the first comma in the tag value that matches the TagName . The purpose of this is to allow the reuse of tags with other libraries, for example, to reuse yaml tags that might have an ,omitempty value appended to the tag value like yaml:"value,omitempty" . |
Then you call FetchEnv
off of envstruct
.
env := envstruct.Envstruct{
Prefix: "prefix",
TagName: "tag",
Parser: envstruct.Parser{
Delimiter: ",",
Unmarshaler: yaml.Unmarshal,
},
}
type Example struct {
Field string `tag:"field"`
}
mystruct := Example{}
err := env.FetchEnv(&mystruct)
if err != nil {
return nil
}
From the example above, if the environment variable PREFIX_FIELD=foo
was set
while it was running then mystruct.Field
will be populated with the string
foo
.
The types of variables that it parses depends on what kind of Unmarshaler
is
passed to the envstruct
. The only special cased types are slices and
maps, which are parsed by envstruct
and then each item is passed to the
Unmarshaler
. Multiple items within one environment variables are separated by
the Delimiter
that is set on the envstruct
.
An example of a slice would be:
PREFIX_SLICE=foo,bar
An example of a map would be:
PREFIX_MAP=foo:foo1,bar:bar1
Each part of the string that is used to build up the environment variable is
uppercased and appended to each other using an underscore _
.
The exact string that is used to fetch the environment variable is built up
using the tags within the struct fields. The TagName
will be used to fetch
the tag value from the struct fields for building up the environment variable
string.
A simple example is a basic struct with a field:
type MyStruct struct {
FieldName string `tag:"field"`
}
FIELD
will be the string that is used to fetch the value of the environment
variable for FieldName
.
If the field does not have a tag that matches the TagName
, it will not be
fetched from an environment variable. envstruct
will only fetch fields that
has a tag that matches the TagName
.
Fields within nested structs are supported, and the environment variable string
is built up with the tag values from each nested struct that has a tag matching
the TagName
.
For example,
type MyStruct struct {
Foo struct {
Bar struct {
FieldName string `tag:"field"`
}
} `tag:"foo"`
}
The example above would result in the string FOO_BAR
to be used to fetch the
environment variable for MyStruct.Foo.Bar.FieldName
. If the Prefix
was set
to PREFIX
, then PREFIX_FOO_BAR
will be used to fetch the environment
variable for MyStruct.Foo.Bar.FieldName
.
The string that is built up using the TagName
which is used to fetch the
environment variable can be overriden using the OverrideName
field. If you
configure the OverrideName
field, any field that contains a tag that matches
the value set in OverrideName
will use the value of that tag to fetch its
environment variable. The override tag will only be recognized on fields on a
struct and not nested structs.
The value of the tag matching the OverrideName
will be used directly, that
means it will not be uppercased, appended with nested struct tags or prefixed
like how the regular built up string using the TagName
is.
For example, in the example below we have set the OverrideName
to be value
override
.
type MyStruct struct {
Foo struct {
Bar struct {
FieldName string `tag:"field" override:"override_field"`
}
} `tag:"foo"`
}
Since FieldName
has a tag override
, the value of the override
value will
be used to fetch the environment variable. In the example, override_field
will be used to fetch the environment variable, rather than FOO_BAR
which
would have been used if the field did not contain the override
tag.
A field can have multiple override tag values that are comma separated. For example,
type MyStruct struct {
FieldName string `tag:"field" override:"O_FIELD1,O_FIELD2"`
}
O_FIELD1
and O_FIELD2
will be used to try and fetch the environment
variable for FieldName
. It is ordered in terms of precedence from left to
right, so if a value is fetched from O_FIELD1
then we will use that value and
not try to fetch using O_FIELD2
.
You can ignore certain tags so that they will not be included in the built up
string for fetching the environment value using the IgnoreTagName
configuration. The string that it is set to a true
value will be used to find
when a field should not be included.
Typically this will be used for nested struct tags, where you do not want to include the nested tag value in the environment variable lookup.
An example below with the IgnoreTagName
set to ignore_env
and TagName
set
to tag
:
type MyStruct struct {
Foo struct {
Bar struct {
FieldName string `tag:"field"`
} `tag:"bar" ignore_env:"true"`
} `tag:"foo"`
}
The example above would result in an environment variable fetch using
FOO_FIELD
where it does not include BAR
within the built up string.
If the ignore_env
was set to false
, then the tag name will be included in
the environment variable string.
If there is a nested struct that is a pointer, envstruct will only traverse it
if it is already initialized. For example, if you have MyStruct
with a nested
Foo
struct that is of a pointer type
type MyStruct struct {
Foo *struct {
FieldName string `tag:"field"`
} `tag:"foo"`
}
Foo
will need to be initialized before it is passed into envstruct
for it
to be able to traverse through the fields within the nested pointer struct.
This is because we don't want to initialize pointers within envstruct
.