envconfig is a library which allows you to parse your configuration from environment variables and fill an arbitrary struct.
See the example to understand how to use it, it's pretty simple.
- Almost all standard types plus
time.Duration
are supported by default. - Slices and arrays
- Arbitrary structs
- Custom types via the Unmarshaler interface.
envconfig takes the hierarchy of your configuration struct and the names of the fields to create a environment variable key.
For example:
var conf struct {
Name string
Shard struct {
Host string
Port int
}
}
This will check for those 3 keys:
- NAME or name
- SHARD_HOST, or shard_host
- SHARD_PORT, or shard_port
envconfig supports having underscores in the key names where there is a word boundary. Now, that term is not super explicit, so let me show you an example:
var conf struct {
Cassandra struct {
SSLCert string
SslKey string
}
}
This will check all of the following keys:
- CASSANDRA_SSL_CERT, CASSANDRA_SSLCERT, cassandra_ssl_cert, cassandra_sslcert
- CASSANDRA_SSL_KEY, CASSANDRA_SSLKEY, cassandra_ssl_key, cassandra_sslkey
If that is not good enough, look just below.
envconfig supports custom environment variable names:
var conf struct {
Name string `envconfig:"myName"`
}
envconfig supports default values:
var conf struct {
Name string `envconfig:"default=Vincent"`
}
envconfig supports optional values:
var conf struct {
Name string `envconfig:"optional"`
Age int `envconfig:"-"`
}
The two syntax are equivalent.
You can of course combine multiple options:
var conf struct {
Name string `envconfig:"default=Vincent,myName"`
}
With slices or arrays, the same naming is applied for the slice. To put multiple elements into the slice or array, you need to separate them with a , (will probably be configurable in the future, or at least have a way to escape)
For example:
var conf struct {
Ports []int
}
This will check for the key PORTS:
- if your variable is 9000 the slice will contain only 9000
- if your variable is 9000,100 the slice will contain 9000 and 100
For slices of structs, it's a little more complicated. The same splitting of slice elements is done with a comma, however, each token must follow
a specific format like this: {<first field>,<second field>,...}
For example:
var conf struct {
Shards []struct {
Name string
Port int
}
}
This will check for the key SHARDS. Example variable content: {foobar,9000},{barbaz,20000}
This will result in two struct defined in the Shards slice.
- support for time.Time values with a layout defined via a field tag
- support for complex types