Attribute Macro config
#[config]
Expand description
Define a configuration type.
§Example
use pavex::config;
#[config(key = "pool")]
#[derive(serde::Deserialize, Debug, Clone)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}
§Guide
Check out the “Configuration” section of Pavex’s guide for a thorough introduction to configuration in Pavex applications.
§Import
Use Blueprint::config
or Blueprint::import
to add the newly-defined configuration type
to your application.
§Arguments
The sections below provide an exhaustive list of all the arguments and flags supported by the config
macro:
Name | Kind | Required |
---|---|---|
key | Argument | Yes |
default_if_missing | Flag | No |
include_if_unused | Flag | No |
never_clone | Flag | No |
§key
The config
macro expects a key
argument.
key
will be used as the name of the corresponding field in the
generated ApplicationConfig
struct.
The provided key must satisfy a few constraints:
- It can’t be empty.
- It must start with a letter.
- It can only contain letters, numbers, and underscores.
- It must be unique within the application.
§Example
use pavex::config;
#[config(key = "pool")]
// 👆 The key for this configuration type.
#[derive(serde::Deserialize, Debug, Clone)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}
§default_if_missing
By default, Pavex considers all configuration types to be required. There must be a value for each configuration key in the source we’re reading from—e.g. a YAML configuration file. If a key is missing, Pavex will return an error.
The default_if_missing
flag disables this behaviour.
Pavex will invoke Default::default()
to provide a default
value if the configuration key was omitted by the configuration source. No error will be raised.
default_if_missing
can only be used on types that implement the Default
trait.
§Example
Consider the following configuration type:
use pavex::config;
#[config(key = "pool", default_if_missing)]
// 👆 The flag
#[derive(serde::Deserialize, Debug, Clone)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}
impl Default for PoolConfig {
fn default() -> Self {
Self {
max_n_connections: 10,
min_n_connections: 2,
}
}
}
The definition of ApplicationConfig
, in the generated server SDK code, will look like this:
#[derive(serde::Deserialize, Debug, Clone)]
pub struct ApplicationConfig {
#[serde(default)]
// 👆 Tell `serde` to use the default value
// if the field is missing.
pub pool: PoolConfig,
// [..other config types..]
}
Therefore, given this YAML configuration file as input,
tls:
enabled: true
# No `pool` entry!
Pavex will initialize PoolConfig
using its default values, rather than returning an error.
§include_if_unused
By default, Pavex will prune unused configuration types from the
final ApplicationConfig
type.
The include_if_unused
flag disables this behaviour.
There will always be an entry in ApplicationConfig
for configuration types
marked as include_if_unused
, even if their value is never accessed by any constructor,
route, or middleware.
§Example
Consider this configuration type:
use pavex::config;
#[config(key = "pool", include_if_unused)]
// 👆 The flag
#[derive(serde::Deserialize, Debug, Clone)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}
The resulting ApplicationConfig
will always contain an entry for PoolConfig
,
even if it’s never used. In the generated server SDK code:
#[derive(Debug, Clone, serde::Deserialize)]
pub struct ApplicationConfig {
pub pool: PoolConfig,
// 👆 You'll always find this field.
// [..other config types..]
}
§never_clone
By default, Pavex will invoke .clone()
on configuration types if it helps to satisfy
Rust’s borrow checker.
The never_clone
flag disables this behaviour:
use pavex::config;
#[config(key = "pool", never_clone)]
// 👆 The flag
#[derive(serde::Deserialize, Debug)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}
Pavex will report an error during the code-generation phase if cloning is required but forbidden.