Axum State
Axum allows providing a "state" struct to
the Router
. Roadster provides its state (DB connection pool,
etc)
in the AppContext
struct, which can
be used either as the Axum state directly. Or, if non-Roadster state is needed for some resource not provided by
Roadster, a custom struct can be used as long as it
implements FromRef
so Roadster can get its AppContext
state from Axum.
FromRef
for custom state
FromRef
can either be derived
#[derive(Clone, FromRef)]
pub struct CustomState {
pub context: AppContext,
pub custom_field: String,
}
or implemented manually
#[derive(Clone)]
pub struct CustomState {
pub context: AppContext,
pub custom_field: String,
}
impl FromRef<CustomState> for AppContext {
fn from_ref(input: &CustomState) -> Self {
input.context.clone()
}
}
Providing state
The app state needs to be provided to the HttpService
when it's created. If
the HttpServiceBuilder
is used to register the service with
the
ServiceRegistry#register_builder
method, the state will be provided automatically when the ServiceRegistry
builds the service.
use roadster::app::context::AppContext;
use roadster::service::http::service::HttpService;
type App = RoadsterApp<AppContext>;
fn build_app() -> App {
RoadsterApp::builder()
// Use the default `AppContext` for this example
.state_provider(|context| Ok(context))
.add_service_provider(move |registry, state| {
Box::pin(async move {
registry
.register_builder(HttpService::builder(Some("/api"), state))
.await?;
Ok(())
})
})
.build()
}