Runtime configuration
Strut primarily aims to remove chores that stand in the way of writing application logic.
Most often this comes down to pre-configuring common public crates, such as tracing or sqlx.
The philosophy of Strut configuration is:
- Reasonable defaults for everything.
- This means minimal configuration is always no configuration at all.
- Customization through files and environment, including:
- Flexible interpretation of human inputs.
- Simple and readable naming conventions.
The entire configuration is represented by the AppConfig struct, which also acts as a facade (a collection of associated function) for accessing the loaded & parsed configuration.
Strut uses the config crate for loading and parsing.
Initial vs live
Strut maintains two distinct versions of configuration:
- Initial configuration is loaded and parsed eagerly on startup.
- Afterward, it remains immutable throughout the lifetime of the application.
- Use the
AppConfigfacade for working with initial config.
- Live configuration may be enabled via the
config-livefeature.- As the name suggests, this configuration may be manually refreshed at any time.
- Use the
AppLiveConfigfacade for working with live config.
Currently all Strut components use the initial config implicitly.
Cargo features
In the basic form, Strut only loads the initial, synchronous AppConfig from the following sources:
The following features may be also enabled:
Feature config-async
Under the hood Strut uses a synchronous ConfigBuilder.
Enable this feature to switch it to asynchronous state.
Then, customize the config builder via a custom ConfigurationWiring.
Feature config-live
By default, Strut loads and parses the configuration only once (the initial config).
Enable this feature to gain the ability to refresh the config at any time via the AppLiveConfig facade.
Config files
Strut automatically loads external configuration files from the config directory located in the current working directory of the running process.
When running the application using Cargo (e.g., cargo run) or via an IDE, the config directory is taken relative to the crate root (where Cargo.toml is located).
You can change the config directory to any relative or absolute path via Launchpad.
File naming convention
- Accepted formats/extensions:
- TOML (
*.toml). - YAML (
*.yamlor*.yml).
- TOML (
- Generic files are applied always.
- Pattern:
config/{any_name}.{ext}
- Pattern:
- Profile-specific files are applied when the file’s profile matches the active profile.
- Patterns:
config/{any_name}.{profile}.{ext}config/{profile}/{any_name}.{ext}
- Patterns:
Within the convention, you can spread the config across arbitrarily named files. These separate key-value maps are merged during loading. When keys overlap, profile-specific values take precedence.
Slugs (config keys)
Strut strives to be permissive when interpreting user-provided config.
All config slugs in Strut are case-insensitive, and only take ASCII alphanumeric characters into account when matching.
This means that slugs like map-s, MapS, maps, and even +++MAP_S+++ are all identical.
This matching style applies to all built-in configuration keys and enumeration-style values (e.g., blue/green, error/warn/info, etc.).
Scalar values like integers or booleans, as well as literal values like file paths are, of course, not slugs.
Some components allow user-provided configuration keys. An example would be a list of database connection handles:
- YAML
- TOML
database:
mysql:
my-database: mysql://username:changeme@example.com:3306/my_database
other-database: mysql://username:changeme@example.com:3306/other_database
[database.mysql]
"my-database" = "mysql://username:changeme@example.com:3306/my_database"
"other-database" = "mysql://username:changeme@example.com:3306/other_database"
Such keys are also slugs.
In the example above, my-database can be retrieved using MyDataBase or any other equivalent slug.
This means that using distinct keys that differ only in punctuation (e.g., value_a and VALUEA) is a logical error (despite being valid YAML/TOML), and will lead to the two keys being squashed together.
Environment config
All config key-values can be overwritten via environment variables. Matching of environment variable names to config keys happens automatically, using a naming convention:
- Always use the
APP_prefix. - Squash individual slugs (config keys) into
SINGLEWORD. - Use underscores
_as slug separators. - Letter case doesn’t really matter, but UPPERCASE is conventional.
It is probably easier to learn this by example:
- Config key:
name.- Corresponding environment variable:
APP_NAME. - Just add the
APP_prefix.
- Corresponding environment variable:
- Config key:
tracing.show_file.- Corresponding environment variable:
APP_TRACING_SHOWFILE. - Squash individual slugs (such as
single_word) intoSINGLEWORD. - Replace dot separators
.with underscores_.
- Corresponding environment variable:
A few more examples:
database.url->APP_DATABASE_URL.database.mysql.some_handle.pool.idle_timeout->APP_DATABASE_MYSQL_SOMEHANDLE_POOL_IDLETIMEOUT.
Strut optionally reads environment defaults from the .env and .env.local files in the same place as it looks for the config directory.
Conventionally, .env is committed to the version control system, but .env.local is not.
You can customize the naming convention for environment variables (and disable environment config altogether) via Launchpad.