#Axum Integration Guide
Version: 0.33.0 Updated: 2026-03-15 Applies to: ranvier-core, ranvier-macros, ranvier-runtime Category: Integration
Combine Axum's ergonomic API with Ranvier's Schematic workflows.
#Overview
Axum is a web framework that focuses on ergonomics and modularity, built on top of Tower. You can integrate Ranvier transitions with Axum handlers to combine:
- Axum: Type-safe extractors, state management, Tower middleware
- Ranvier: Schematic visualization, Bus propagation, composable logic
#Integration Pattern
The recommended approach is to call Ranvier transitions from Axum handlers:
#Calling Ranvier Transition from Axum Handler
use axum::{
extract::{State, Json},
http::StatusCode,
response::IntoResponse,
Router,
};
use ranvier_core::{Bus, Outcome};
use ranvier_macros::transition;
use ranvier_runtime::Axon;
use std::sync::Arc;
// Shared app state
#[derive(Clone)]
struct AppState {
pipeline: Axon<CreateUser, User, AppError, ()>,
}
// Ranvier transition
#[transition]
async fn create_user(
input: CreateUser,
_res: &(),
bus: &mut Bus
) -> Outcome<User, AppError> {
// Your business logic
Outcome::Next(User { id: 1, name: input.name })
}
// Axum handler
async fn create_user_handler(
State(state): State<Arc<AppState>>,
Json(payload): Json<CreateUser>
) -> impl IntoResponse {
let mut bus = Bus::new();
match state.pipeline.execute(payload, &(), &mut bus).await {
Outcome::Next(user) => (StatusCode::CREATED, Json(user)).into_response(),
Outcome::Fault(err) => (StatusCode::BAD_REQUEST, Json(err)).into_response(),
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}
// Axum app
#[tokio::main]
async fn main() {
let pipeline = Axon::simple::<AppError>("create-user")
.then(create_user);
let state = Arc::new(AppState { pipeline });
let app = Router::new()
.route("/users", axum::routing::post(create_user_handler))
.with_state(state);
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}#Using Axum Extractors with Ranvier
use axum::{
extract::{Extension, TypedHeader},
headers::Authorization,
headers::authorization::Bearer,
};
async fn protected_handler(
TypedHeader(auth): TypedHeader<Authorization<Bearer>>, // Axum extractor
State(state): State<Arc<AppState>>,
Json(data): Json<RequestData>
) -> impl IntoResponse {
let mut bus = Bus::new();
// Put extracted token in Bus for Ranvier transitions
bus.insert(auth.token().to_string());
match state.pipeline.execute(data, &(), &mut bus).await {
Outcome::Next(result) => (StatusCode::OK, Json(result)).into_response(),
Outcome::Fault(err) => (StatusCode::UNAUTHORIZED, Json(err)).into_response(),
_ => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}#Sharing State Between Axum and Ranvier
// Axum state includes both app config and Ranvier pipelines
#[derive(Clone)]
struct AppState {
db: Arc<DatabasePool>,
order_pipeline: Axon<Order, OrderResult, AppError, ()>,
user_pipeline: Axon<CreateUser, User, AppError, ()>,
}
// In handler, access both Axum state and execute Ranvier pipeline
async fn process_order(
State(state): State<Arc<AppState>>,
Json(order): Json<Order>
) -> impl IntoResponse {
let mut bus = Bus::new();
// Put Axum-managed resources in Bus for Ranvier transitions
bus.insert(state.db.clone());
state.order_pipeline.execute(order, &(), &mut bus).await
// ... handle result
}#When to Use This Approach
Good for:
- Existing Axum apps adding Ranvier for complex workflows
- Teams familiar with Axum's type-safe extractors
- Want Tower middleware with Ranvier business logic
- Need Ranvier's Schematic visualization for multi-step processes
Consider:
- State bridging: You need to bridge Axum
Stateto Ranvier Bus manually - Middleware visibility: Axum middleware (Tower layers) won't appear in Ranvier Schematic
- Testing: Integration tests for Axum handlers, unit tests for Ranvier transitions
#Trade-offs
| Aspect | Benefit | Limitation |
|---|---|---|
| Extractors | Axum's type-safe extractors (Json, State, TypedHeader) | Manual bridging to Bus required |
| Tower Middleware | Full Tower ecosystem via Axum layers | Not visible in Ranvier Schematic |
| State Management | Axum's ergonomic State sharing | State + Bus dual management |
| Business Logic | Ranvier transitions with Schematic visualization | Extra boilerplate for Axum-Ranvier integration |
#Comparison with Alternatives
- vs Pure Ranvier: Axum integration gives you type-safe extractors and Tower middleware, but loses some Schematic visibility
- vs Tower Integration: Axum provides higher-level ergonomics on top of Tower (extractors, routing)
- vs actix Integration: Axum uses type-based extractors, actix uses trait-based extractors
#Related Documents
- Tower Integration โ Axum is built on Tower
- actix-web Integration โ Alternative framework integration