axum_reverse_proxy/
router.rs

1use crate::proxy::ReverseProxy;
2use axum::routing::Router;
3use hyper_util::client::legacy::connect::Connect;
4
5/// Enables conversion from a `ReverseProxy` into an Axum `Router`.
6///
7/// This implementation allows the reverse proxy to be easily integrated into an Axum
8/// application. It handles:
9///
10/// - Path-based routing using the configured base path
11/// - State management using `Arc` for thread-safety
12/// - Fallback handling for all HTTP methods
13///
14/// # Example
15///
16/// ```rust
17/// use axum::Router;
18/// use axum_reverse_proxy::ReverseProxy;
19///
20/// let proxy = ReverseProxy::new("/api", "https://api.example.com");
21/// let app: Router = proxy.into();
22/// ```
23impl<C, S> From<ReverseProxy<C>> for Router<S>
24where
25    C: Connect + Clone + Send + Sync + 'static,
26    S: Send + Sync + Clone + 'static,
27{
28    fn from(proxy: ReverseProxy<C>) -> Self {
29        let path = proxy.path().to_string();
30        let proxy_router = Router::<S>::new().fallback_service(proxy);
31
32        if ["", "/"].contains(&path.as_str()) {
33            proxy_router
34        } else {
35            Router::new().nest(&path, proxy_router)
36        }
37    }
38}
39
40use crate::balanced_proxy::{BalancedProxy, DiscoverableBalancedProxy};
41
42impl<C, S> From<BalancedProxy<C>> for Router<S>
43where
44    C: Connect + Clone + Send + Sync + 'static,
45    S: Send + Sync + Clone + 'static,
46{
47    fn from(proxy: BalancedProxy<C>) -> Self {
48        let path = proxy.path().to_string();
49        let proxy_router = Router::<S>::new().fallback_service(proxy);
50
51        if ["", "/"].contains(&path.as_str()) {
52            proxy_router
53        } else {
54            Router::new().nest(&path, proxy_router)
55        }
56    }
57}
58
59impl<C, D, S> From<DiscoverableBalancedProxy<C, D>> for Router<S>
60where
61    C: Connect + Clone + Send + Sync + 'static,
62    D: tower::discover::Discover + Clone + Send + Sync + 'static,
63    D::Service: Into<String> + Send,
64    D::Key: Clone + std::fmt::Debug + Send + Sync + std::hash::Hash,
65    D::Error: std::fmt::Debug + Send,
66    S: Send + Sync + Clone + 'static,
67{
68    fn from(proxy: DiscoverableBalancedProxy<C, D>) -> Self {
69        let path = proxy.path().to_string();
70        let proxy_router = Router::<S>::new().fallback_service(proxy);
71
72        if ["", "/"].contains(&path.as_str()) {
73            proxy_router
74        } else {
75            Router::new().nest(&path, proxy_router)
76        }
77    }
78}