New configuration entries
Use the #[config] attribute to define a new configuration entry:
use pavex::config;
use redact::Secret;
#[config(key = "database")]
#[derive(serde::Deserialize, Debug, Clone)] // (1)!
pub struct DatabaseConfig {
pub username: String,
pub password: Secret<String>,
pub host: String,
pub database_name: String,
pub require_ssl: bool,
}
- Deriving the required traits.
The #[config] attribute expects a unique configuration key as argument.
Required traits
The annotated type must implement the Debug, Clone, and serde::Deserialize traits.
As you have seen in the example above, the required trait implementations can be derived automatically. If necessary, check out serde's documentation for more information on how to customize the deserialization process.
Registration
Use an import to register in bulk all the configuration entries defined in the current crate:
use pavex::{Blueprint, blueprint::from};
pub fn blueprint() -> Blueprint {
let mut bp = Blueprint::new();
bp.import(from![crate]); // (1)!
// [...]
}
- You can also import configuration entries from other crates or specific modules.
Alternatively, register configuration entries one by one using Blueprint::config:
use super::DATABASE_CONFIG;
use pavex::Blueprint;
pub fn blueprint() -> Blueprint {
let mut bp = Blueprint::new();
bp.config(DATABASE_CONFIG); // (1)!
// [...]
}
DATABASE_CONFIGis a strongly-typed constant generated by the#[config]attribute on theDatabaseConfigtype.
Check out the documentation on component ids for more details.
Configuration key
The configuration key uniquely identifies a configuration entry within a Pavex application. It must start with a letter and can contain letters, digits and underscores.
Every configuration entry becomes a field in ApplicationConfig, and the configuration key is used as the field name.
The key determines the expected configuration schema—e.g. which environment variables can be used to
set its value and the structure of configuration files.
Lifecycle
Configuration entries are treated as singletons from Pavex's dependency injection system.
Most configuration entries are only needed to construct other singletons,
so they'll be discarded after ApplicationState::new returns.
If a configuration entry is needed at runtime (e.g. to configure the behaviour of middleware or a request handler),
it'll be added as a field to ApplicationState.
In this case, Pavex will expect the configuration type to implement the Send and Sync traits in addition
to the other trait requirements.