go-boot-config lets you externalize your configuration so that you can work with the same application code in different environments. You can use properties files, YAML files, environment variables, and command-line arguments to externalize configuration.
Property values can be retrieved directly through go-boot-config module, accessed through go-boot-config ’s Environment
abstraction
The idea behind go-boot-config is to standartized config retrieval in Go, to be able to build smart modules around.
Before retrieving your parameter you need load the Environment
package main
import "github.com/furkilic/go-boot-config/pkg/go-boot-config"
func main() {
gobootconfig.Load()
myString, _ := gobootconfig.GetString("myString")
myStringWithDefault := gobootconfig.GetStringWithDefault("myStringDef", "myDefault")
// Play with confs....
}
my-app --myString=myValue --myStringDef=${myString}
You can easily retrieve few types of data (XXX being String, Bool, Int or Float):
- GetXXX(key) : retrieve XXX type of key or error
myVal, err := gobootconfig.GetString("myString")
- GetXXXWithDefault(key, defaultValue) : retrieve XXX type of key or defaultValue
myValOrDefault, err := gobootconfig.GetStringWithDefault("myString", "myDefault")
- GetXXXSlice(key) : retrieve XXX type slice of key or error
myStringSlice, err := gobootconfig.GetStringSlice("myStringSlice")
- GetXXXSliceWithDefault(key, defaultValue) : retrieve XXX type slice of key or defaultValue
myStringSliceOrDefault, err := gobootconfig.GetStringSliceWithDefault("myStringSlice", []string{"default"})
- GetObject(key, theObjectAdress) : inject value of key in theObjectAdress or error if not found
var myObj MyObj
err := gobootconfig.GetObj("myObject", &myObj)
go-boot-config uses a very particular PropertySource order that is designed to allow sensible overriding of values. Properties are considered in the following order:
- Command line arguments.
- OS environment variables.
- RandomValuePropertySource that has properties only in random.*.
- Profile-specific application properties (application-{profile}.properties and YAML variants).
- Application properties (application.properties and YAML variants).
- Default properties
package main
import "github.com/furkilic/go-boot-config/pkg/go-boot-config"
func main() {
gobootconfig.Load()
name, err := gobootconfig.GetString("name")
// name has the value from the property sources
// err if name does not exists
}
On your application config path (for example configs) you can have an application.properties
file that provides
a sensible default property value for name
.
For one-off testing, you can launch with a specific command line switch (for example, my-app --name="GoBootConfig"
).
The randomPropertySource
is useful for injecting random values (for example, into secrets or test cases).
It can produce integers, floats, uuids, or strings, as shown in the following example:
my.secret=${random.value}
my.number=${random.int}
my.float=${random.float}
my.uuid=${random.uuid}
By default, go-boot-config converts any command line option arguments
(that is, arguments starting with --
, such as --server.port=9000
or --server.port 9000
) to a property
and
adds them to the go-boot-config Environment
.
As mentioned previously, command line properties always take precedence over other property sources.
go-boot-config loads properties from application.properties
files in the following locations and adds them to the Environment
:
- A
/configs
subdirectory of the current directory - The current directory
The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).
❕ You can also use YAML
('.yml' or '.yaml') files as an alternative to '.properties'.
If you do not like application.properties
as the configuration file name, you can switch to another file
name by specifying a go.config.name
environment property.
You can also refer to an explicit location by using the go.config.location
environment property
(which is a comma-separated list of directory locations or file paths).
The following example shows how to specify a different file name:
./my-app --go.config.name=my-app
The following example shows how to specify two locations:
./my-app --go.config.location=configs/default.properties,configs/override.properties
go.config.name
and go.config.location
are used very early to determine which files have to be loaded.
They must be defined as an environment property (typically an OS environment variable or a command-line argument).
If go.config.location
contains directories (as opposed to files, and, at runtime,
be appended with the names generated from go.config.name
before being loaded, including profile-specific file names).
Files specified in go.config.location
are used as-is, with no support for profile-specific variants, and are overridden
by any profile-specific properties.
When custom config locations are configured by using go.config.location
, they replace the default locations
❕ If you use environment variables rather than properties, most operating systems disallow period-separated key names,
but you can use underscores instead (for example, GO_CONFIG_NAME
instead of go.config.name
).
In addition to application.properties
files, profile-specific properties can also be defined by using the following
naming convention: application-{profile}.properties
. The Environment
has a set of default profiles (by default, default
)
that are used if no active profiles are set.
In other words, if no profiles are explicitly activated, then properties from application-default.properties
are loaded.
Profile-specific properties are loaded from the same locations as standard application.properties
, with profile-specific
files always overriding the non-specific ones.
If several profiles are specified, a first-wins strategy applies.
For example, profiles specified by the go.profiles.active
property are added after those configured and therefore take precedence.
❕ If you have specified any files in go.config.location
, profile-specific variants of those files are
not considered. Use directories in go.config.location
if you want to also use profile-specific properties.
The values in application.properties
are filtered through the existing Environment
when they are used,
so you can refer back to previously defined values (for example, from OS environment properties).
app.name=MyApp
app.description=${app.name} is using go-boot-config
app.nonexisting=${app.what:-mydefault} is not existing so 'mydefault' will be used
YAML
is a superset of JSON and, as such, is a convenient format for specifying hierarchical configuration data.
go-boot-config supports YAML as an alternative to properties by using gopkg.in/yaml.v2
YAML
is a superset of JSON and, as such, is a convenient format for specifying hierarchical configuration data.
go-boot-config supports YAML as an alternative to properties by using gopkg.in/yaml.v2
Property Source | Simple | Slice |
---|---|---|
Command line arguments | nospacelowercase, camelCase, kebab-case, or underscore_notation | Comma-separated values or Mulitple declaration |
--myapp.mystring=myvalue |
--myapp.myslice=myvalue1,myvalue2 or --myapp.myslice=myvalue1 --myapp.myslice=myvalue2 |
|
Environment Variables | Upper case format with underscore as the delimiter. _ should not be used within a property name |
Comma-separated values |
MYAPP_MYSTRING=myvalue |
MYAPP_MYSLICE=myvalue1,myvalue2 |
|
Properties Files | nospacelowercase, camelCase, kebab-case, or underscore_notation | Comma-separated values |
myapp.mystring=myvalue |
myapp.myslice=myvalue1,myvalue2 |
|
YAML Files | nospacelowercase, camelCase, kebab-case, or underscore_notation | Standard YAML list syntax or comma-separated values |
myapp: {mystring: myvalue} |
myapp: {myslice: [myvalue1, myvalue2]} |
To retrieve the property nospacelowercase
is recommended
gobootconfig.GetString("myapp.mystring")
// Works with :
// myapp.mystring
// my-app.my-string
// myApp.myString
// my_app.my_string
// MYAPP_MYSTRING
If you want to retrieve a specific index of a list value, you can use standard list syntax using [index]
// myapp.myslice=val1,val2,val3
gobootconfig.GetString("myapp.myslice[1]")
// Will return :
// val2