Rapina's #[derive(Config)] macro loads configuration from environment variables and .env files. The State<T> extractor gives handlers access to shared application state, including your config.
#[derive(Config)]
struct AppConfig {
app_name: String, // reads APP_NAME env var
version: String, // reads VERSION env var
}Config values are loaded at startup — if a required variable is missing, the app crashes immediately instead of failing at runtime. This is the "fail fast" principle.
Access it in handlers via State<T>:
async fn handler(State(config): State<AppConfig>) -> Json<T> {
// config.app_name, config.version
}AppConfig struct with #[derive(Config)] and fields app_name: String and version: StringState(config): State<AppConfig> as a handler parameterconfig.app_name and the version in the health responseuse rapina::prelude::*;
#[derive(Config)]
struct AppConfig {
app_name: String,
version: String,
}
#[derive(Serialize, JsonSchema)]
struct HealthResponse {
status: String,
app_name: String,
version: String,
}
#[public]
#[get("/health")]
async fn health(State(config): State<AppConfig>) -> Json<HealthResponse> {
Json(HealthResponse {
status: "ok".into(),
app_name: config.app_name.clone(),
version: config.version.clone(),
})
}