Rapina Rapina /Tutorial
Read the docs

State and Config

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
}

Assignment

  1. Create an AppConfig struct with #[derive(Config)] and fields app_name: String and version: String
  2. Add State(config): State<AppConfig> as a handler parameter
  3. Include config.app_name and the version in the health response
Show answer
use 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(),
    })
}
Tests
All tests passing — nice work!
main.rs
Response Preview
Complete the tests to see the response preview.
Previous 5 / 6 Next