#Axum 통합 가이드

버전: 0.33.0 최종 업데이트: 2026-03-15 적용 대상: ranvier-core, ranvier-macros, ranvier-runtime 카테고리: 통합


Axum의 사용하기 편한 API와 Ranvier의 Schematic 워크플로우를 결합하세요.

#개요

Axum은 Tower 위에 구축되어 사용 편의성과 모듈성에 초점을 맞춘 웹 프레임워크입니다. Ranvier transition을 Axum 핸들러와 통합하면 다음을 함께 활용할 수 있습니다:

  • Axum: 타입 안전 extractor, 상태 관리, Tower 미들웨어
  • Ranvier: Schematic 시각화, Bus 전파, 조합 가능한 로직

#통합 패턴

Axum 핸들러 안에서 Ranvier transition을 호출하는 방식을 권장합니다:

#Axum 핸들러에서 Ranvier Transition 호출

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;

// 공유 앱 상태
#[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> {
    // 비즈니스 로직
    Outcome::Next(User { id: 1, name: input.name })
}

// Axum 핸들러
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 앱
#[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();
}

#Ranvier와 함께 Axum Extractor 사용

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();

    // 추출된 토큰을 Ranvier transition을 위해 Bus에 저장
    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(),
    }
}

#Axum과 Ranvier 간 상태 공유

// Axum 상태에 앱 설정과 Ranvier 파이프라인 모두 포함
#[derive(Clone)]
struct AppState {
    db: Arc<DatabasePool>,
    order_pipeline: Axon<Order, OrderResult, AppError, ()>,
    user_pipeline: Axon<CreateUser, User, AppError, ()>,
}

// 핸들러에서 Axum 상태 접근과 Ranvier 파이프라인 실행 모두 수행
async fn process_order(
    State(state): State<Arc<AppState>>,
    Json(order): Json<Order>
) -> impl IntoResponse {
    let mut bus = Bus::new();

    // Axum이 관리하는 리소스를 Ranvier transition을 위해 Bus에 저장
    bus.insert(state.db.clone());

    state.order_pipeline.execute(order, &(), &mut bus).await
        // ... 결과 처리
}

#이 방식이 적합한 경우

적합한 경우:

  1. 기존 Axum 앱에 복잡한 워크플로우용으로 Ranvier를 추가할 때
  2. Axum의 타입 안전 extractor에 익숙한 팀
  3. Ranvier 비즈니스 로직과 함께 Tower 미들웨어를 쓰고 싶을 때
  4. 다단계 프로세스에 Ranvier Schematic 시각화가 필요할 때

고려사항:

  • 상태 연결: Axum State를 Ranvier Bus로 수동으로 연결해야 함
  • 미들웨어 가시성: Axum 미들웨어(Tower 레이어)는 Ranvier Schematic에 표시되지 않음
  • 테스트: Axum 핸들러에 대한 통합 테스트, Ranvier transition에 대한 단위 테스트

#트레이드오프

측면 장점 제한사항
Extractor Axum의 타입 안전 extractor (Json, State, TypedHeader) Bus로의 수동 연결 필요
Tower 미들웨어 Axum 레이어를 통한 전체 Tower 생태계 Ranvier Schematic에서 보이지 않음
상태 관리 Axum의 편리한 State 공유 State + Bus 이중 관리
비즈니스 로직 Schematic 시각화가 포함된 Ranvier transition Axum-Ranvier 통합을 위한 추가 보일러플레이트

#대안과의 비교

  • 순수 Ranvier 대비: 타입 안전 extractor와 Tower 미들웨어를 쓸 수 있지만 Schematic 가시성 일부를 잃음
  • Tower 통합 대비: Axum은 Tower 위에 더 높은 수준의 편의 기능 제공 (extractor, 라우팅)
  • actix 통합 대비: Axum은 타입 기반, actix는 트레이트 기반 extractor 사용

#관련 문서

  • Tower 통합 — Axum은 Tower 위에 구축됨
  • actix-web 통합 — 대안 프레임워크 통합