🗼 Tower 통합 가이드
Tower의 Service/Layer 생태계와 Ranvier의 Transition/Outcome/Bus 패러다임을 활용하세요
개요
Tower는
견고한 네트워킹 클라이언트와 서버를 구축하기 위한 모듈식이고 재사용 가능한 컴포넌트 라이브러리입니다. Service 트레이트와 Layer 미들웨어 추상화를 제공하며,
많은 Rust 웹 프레임워크(Axum, Tonic, Hyper 등)의 기반이 됩니다.
Tower와 Ranvier
Ranvier는 "Opinionated Core, Flexible Edges" 원칙을 따릅니다:
- Core (Opinionated): Transition/Outcome/Bus/Schematic 패러다임은 협상 불가
- Edges (Flexible): 경계에서 Tower, actix, Axum 또는 모든 Rust 도구 사용 가능
즉, Tower의 Service와 Layer 미들웨어를 Ranvier 트랜지션과
함께 사용하여 두 세계의 장점을 모두 활용할 수 있습니다:
- Tower: CORS, 추적, 타임아웃, 속도 제한, 인증을 위한 검증된 미들웨어
- Ranvier: Schematic 시각화, Bus 전파, 조합 가능한 트랜지션
통합 패턴
Tower와 Ranvier를 통합하는 두 가지 주요 패턴이 있습니다:
패턴 1: Tower Layer로 Ranvier 핸들러 래핑
Ranvier 트랜지션 주변에서 HTTP 관심사(CORS, 추적, 타임아웃)에 Tower 레이어 사용:
use tower::ServiceBuilder;
use tower_http::{
cors::CorsLayer,
trace::TraceLayer,
timeout::TimeoutLayer,
};
let service = ServiceBuilder::new()
.layer(CorsLayer::permissive())
.layer(TraceLayer::new_for_http())
.layer(TimeoutLayer::new(Duration::from_secs(30)))
.service(ranvier_adapter); // ← Ranvier 핸들러 사용 시기: 검증된 HTTP 미들웨어(CORS, 추적)가 필요한 경우
패턴 2: 인증을 위한 Tower Service
인증에 Tower의 AsyncRequireAuthorizationLayer를 사용한 후 Ranvier로 전달:
use tower_http::auth::{AsyncAuthorizeRequest, AsyncRequireAuthorizationLayer};
#[derive(Clone)]
struct JwtAuthorizer { secret: String }
impl<B> AsyncAuthorizeRequest<B> for JwtAuthorizer {
type RequestBody = B;
type ResponseBody = String;
type Future = Ready<Result<Request<B>, Response<String>>>;
fn authorize(&mut self, mut request: Request<B>) -> Self::Future {
// JWT 검증 로직...
let auth_ctx = validate_jwt(token, &self.secret)?;
request.extensions_mut().insert(auth_ctx);
ready(Ok(request))
}
}
let service = ServiceBuilder::new()
.layer(AsyncRequireAuthorizationLayer::new(JwtAuthorizer { secret }))
.service(ranvier_adapter); 사용 시기: 기존 Tower 인증 레이어가 있거나 Tower 기반 서비스와 통합해야 하는 경우
📘 참고
두 패턴 모두 유효합니다. 패턴 1은 HTTP 관심사에 더 간단하고, 패턴 2는 요청/응답 흐름에 대한 완전한 제어를 제공합니다. 자세한 비교는 트레이드오프 섹션을 참조하세요.
인증 예제 안내
Tower + Ranvier 인증의 전체 예제는 examples/auth-tower-integration을 참조하세요.
예제가 보여주는 것
- 두 가지 접근법: 수동
Layer + Service구현(교육용)과 고수준AsyncAuthorizeRequest트레이트(권장) - JWT 검증: Tower 레이어가 JWT를 검증하고
AuthContext를 요청 확장에 저장 - Ranvier 트랜지션: 비즈니스 로직이 Bus에서
AuthContext를 읽음(어댑터가 확장에서 추출)
핵심 통찰
Tower가 토큰 검증 → AuthContext를 request.extensions()에 저장 → 어댑터가 Bus로 추출 → Ranvier 트랜지션이 Bus에서 접근.
예제 실행
cd examples/auth-tower-integration
cargo run
# 출력:
# INFO Tower auth layer configured (JWT validation)
# INFO Ranvier pipeline configured (business logic)
# ✅ Success: {"message":"Hello, alice! (Verified by Tower)",...}Tower 통합 사용 시기
✅ 좋은 사용 사례
- 기존 Tower 앱이 있고 Ranvier를 점진적으로 추가하려는 경우
- 팀이 이미 Tower를 알고 있고 그 지식을 활용하고 싶은 경우
- 특정 Tower 미들웨어(CORS, 속도 제한, 압축)가 필요한 경우
- Tower를 사용하는 다른 프레임워크에서 마이그레이션(Axum, Tonic)하는 경우
- Ranvier에서 재구현하지 않고 검증된 미들웨어를 원하는 경우
❌ 권장하지 않는 경우
- 새 프로젝트를 시작하고 완전한 Schematic 시각화를 원하는 경우 (대신 순수 Ranvier 사용)
- Bus를 통한 타입 안전 컨텍스트 전파를 우선시하는 경우 (Tower는 요청 확장 사용)
- 트랜지션을 독립적으로 테스트하려는 경우 (Tower 통합은 HTTP 모의 객체 필요)
💡 권장사항
새 프로젝트의 경우 Transition 기반 인증 (examples/auth-transition)을 선호하세요. 더 나은 Schematic 시각화, Bus 전파, 테스트 가능성을 제공합니다.
기존 Tower 앱에서 점진적 마이그레이션하거나 Ranvier가 제공하지 않는 특정 Tower 미들웨어가 필요한 경우 Tower 통합을 사용하세요.
트레이드오프
Tower 통합에는 장점과 한계가 모두 있습니다:
| 측면 | Tower 통합 | 순수 Ranvier (Transition 기반) |
|---|---|---|
| 생태계 호환성 | ✅ Tower 레이어 전체 접근 | ❌ Ranvier 전용 |
| Schematic 시각화 | ❌ Tower 레이어는 불투명 | ✅ Circuit 뷰에서 완전한 가시성 |
| 컨텍스트 전파 | ⚠️ 요청 확장 (런타임) | ✅ Bus (컴파일 타임 타입 안전) |
| 테스팅 | ⚠️ 통합 테스트 필요 | ✅ 쉬운 단위 테스트 (Bus 주입) |
| 팀 온보딩 | ✅ Tower 지식 활용 | ⚠️ Ranvier 패러다임 학습 |
| 보일러플레이트 | ❌ 50-150 줄 (Service 트레이트) | ✅ 20 줄 (transition 매크로) |
| 성능 | ✅ 동일 (제로 코스트) | ✅ 동일 (제로 코스트) |
범례: ✅ 강력한 장점 | ⚠️ 주의사항과 함께 사용 가능 | ❌ 중요한 제한사항