> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/tokio-rs/axum/llms.txt
> Use this file to discover all available pages before exploring further.

# Router

> The router type for composing handlers and services

The router type for composing handlers and services.

`Router<S>` means a router that is *missing* a state of type `S` to be able to handle requests. Thus, only `Router<()>` (i.e. without missing state) can be passed to `serve`. See `Router::with_state` for more details.

## Constructor

<ParamField path="Router::new()" type="fn() -> Router<S>">
  Create a new `Router`.

  Unless you add additional routes this will respond with `404 Not Found` to all requests.

  ```rust theme={null}
  use axum::Router;

  let app = Router::new();
  ```
</ParamField>

## Routing methods

<ParamField path="route" type="fn(self, path: &str, method_router: MethodRouter<S>) -> Self">
  Add a route to the router.

  The path can contain dynamic segments starting with `:` or catch-all segments starting with `*`.

  ```rust theme={null}
  use axum::{Router, routing::get};

  let app = Router::new()
      .route("/", get(|| async { "Hello, World!" }))
      .route("/users/:id", get(|| async { "User profile" }));
  ```
</ParamField>

<ParamField path="route_service" type="fn<T>(self, path: &str, service: T) -> Self">
  Add a service as a route.

  Similar to `route` but accepts any `Service` instead of a `MethodRouter`.

  **Note:** Cannot be used with `Router`s - use `nest` instead.

  ```rust theme={null}
  use axum::{Router, extract::Request};
  use tower::service_fn;
  use std::convert::Infallible;

  let service = tower::service_fn(|request: Request| async {
      Ok::<_, Infallible>("Hello from service")
  });

  let app = Router::new()
      .route_service("/service", service);
  ```
</ParamField>

<ParamField path="nest" type="fn(self, path: &str, router: Self) -> Self">
  Nest another router at a given path.

  All routes in the nested router will be prefixed with the given path. The path cannot be empty or `/` - use `merge` instead.

  ```rust theme={null}
  use axum::{Router, routing::get};

  let api_routes = Router::new()
      .route("/users", get(|| async { "List users" }))
      .route("/posts", get(|| async { "List posts" }));

  let app = Router::new()
      .nest("/api", api_routes);
  // Routes: /api/users, /api/posts
  ```
</ParamField>

<ParamField path="nest_service" type="fn<T>(self, path: &str, service: T) -> Self">
  Like `nest`, but accepts an arbitrary `Service`.

  The path cannot be empty or `/`.

  ```rust theme={null}
  use axum::{Router, extract::Request};
  use tower::service_fn;
  use std::convert::Infallible;

  let service = tower::service_fn(|request: Request| async {
      Ok::<_, Infallible>("Nested service")
  });

  let app = Router::new()
      .nest_service("/service", service);
  ```
</ParamField>

<ParamField path="merge" type="fn<R>(self, other: R) -> Self where R: Into<Self>">
  Merge two routers into one.

  This is useful for combining multiple routers that have routes at the root level. Both routers cannot have a custom fallback.

  ```rust theme={null}
  use axum::{Router, routing::get};

  let app = Router::new()
      .route("/foo", get(|| async { "foo" }));

  let api = Router::new()
      .route("/bar", get(|| async { "bar" }));

  let merged = app.merge(api);
  // Routes: /foo, /bar
  ```
</ParamField>

## Middleware methods

<ParamField path="layer" type="fn<L>(self, layer: L) -> Self">
  Apply a `tower::Layer` to the router.

  The layer will be applied to all routes and the fallback.

  ```rust theme={null}
  use axum::{Router, routing::get};
  use tower_http::trace::TraceLayer;

  let app = Router::new()
      .route("/", get(|| async { "Hello" }))
      .layer(TraceLayer::new_for_http());
  ```
</ParamField>

<ParamField path="route_layer" type="fn<L>(self, layer: L) -> Self">
  Apply a `tower::Layer` to the router's routes, but not the fallback.

  This is useful when you want middleware to only apply to matched routes.

  ```rust theme={null}
  use axum::{Router, routing::get};
  use tower_http::compression::CompressionLayer;

  let app = Router::new()
      .route("/api/data", get(|| async { "data" }))
      .route_layer(CompressionLayer::new())
      .fallback(|| async { "Not found" });
  // Compression applies to /api/data but not the fallback
  ```
</ParamField>

## Fallback methods

<ParamField path="fallback" type="fn<H, T>(self, handler: H) -> Self">
  Add a fallback handler for requests that don't match any routes.

  ```rust theme={null}
  use axum::{Router, routing::get, http::StatusCode};

  let app = Router::new()
      .route("/", get(|| async { "Home" }))
      .fallback(|| async { (StatusCode::NOT_FOUND, "Page not found") });
  ```
</ParamField>

<ParamField path="fallback_service" type="fn<T>(self, service: T) -> Self">
  Add a fallback `Service` for requests that don't match any routes.

  Like `fallback` but accepts a `Service` instead of a handler.

  ```rust theme={null}
  use axum::{Router, extract::Request};
  use tower::service_fn;
  use std::convert::Infallible;

  let service = tower::service_fn(|_: Request| async {
      Ok::<_, Infallible>("Fallback service")
  });

  let app = Router::new()
      .fallback_service(service);
  ```
</ParamField>

<ParamField path="method_not_allowed_fallback" type="fn<H, T>(self, handler: H) -> Self">
  Set a custom handler for 405 Method Not Allowed responses.

  This handler is called when a route matches the path but not the HTTP method.

  ```rust theme={null}
  use axum::{Router, routing::get, http::StatusCode};

  let app = Router::new()
      .route("/", get(|| async { "GET only" }))
      .method_not_allowed_fallback(|| async {
          (StatusCode::METHOD_NOT_ALLOWED, "Method not allowed")
      });
  ```
</ParamField>

<ParamField path="reset_fallback" type="fn(self) -> Self">
  Reset the fallback to its default.

  Useful to merge two routers with fallbacks, as `merge` doesn't allow both routers to have an explicit fallback. Use this method to remove the one you want to discard before merging.

  ```rust theme={null}
  use axum::{Router, routing::get};

  let app = Router::new()
      .route("/", get(|| async { "Home" }))
      .fallback(|| async { "Custom 404" })
      .reset_fallback();
  ```
</ParamField>

## State management

<ParamField path="with_state" type="fn<S2>(self, state: S) -> Router<S2>">
  Provide the state for the router.

  This converts a `Router<S>` (missing state of type `S`) into a `Router<()>` that can be served.

  ```rust theme={null}
  use axum::{Router, routing::get, extract::State};

  #[derive(Clone)]
  struct AppState {
      db: String,
  }

  let app = Router::new()
      .route("/", get(|State(state): State<AppState>| async move {
          format!("Connected to: {}", state.db)
      }))
      .with_state(AppState { db: "postgres://...".to_string() });
  ```
</ParamField>

## Service conversion

<ParamField path="into_make_service" type="fn(self) -> IntoMakeService<Self>">
  Convert this router into a `MakeService`.

  Only available for `Router<()>` (routers without missing state).

  ```rust theme={null}
  use axum::{Router, routing::get};

  let app = Router::new()
      .route("/", get(|| async { "Hello, World!" }));

  # async {
  let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
  axum::serve(listener, app).await;
  # };
  ```
</ParamField>

<ParamField path="into_make_service_with_connect_info" type="fn<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C>">
  Convert the router into a `MakeService` which stores information about the incoming connection.

  Requires the `tokio` feature.

  ```rust theme={null}
  use axum::{Router, routing::get, extract::ConnectInfo};
  use std::net::SocketAddr;

  async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
      format!("Hello {addr}")
  }

  let app = Router::new().route("/", get(handler));

  # async {
  let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
  axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>()).await;
  # };
  ```
</ParamField>

<ParamField path="as_service" type="fn<B>(&mut self) -> RouterAsService<'_, B, S>">
  Convert the router into a borrowed `Service` with a fixed request body type.

  This is mainly used when calling `Router` in tests to aid type inference.

  ```rust theme={null}
  use axum::{Router, routing::get, http::Request, body::Body};
  use tower::{Service, ServiceExt};

  # async fn example() -> Result<(), Box<dyn std::error::Error>> {
  let mut router = Router::new().route("/", get(|| async {}));
  let request = Request::new(Body::empty());
  let response = router.as_service().ready().await?.call(request).await?;
  # Ok(())
  # }
  ```
</ParamField>

<ParamField path="into_service" type="fn<B>(self) -> RouterIntoService<B, S>">
  Convert the router into an owned `Service` with a fixed request body type.

  Similar to `as_service` but returns an owned `Service`.

  ```rust theme={null}
  use axum::{Router, routing::get};

  let router = Router::new()
      .route("/", get(|| async { "Hello" }))
      .into_service();
  ```
</ParamField>

## Utility methods

<ParamField path="has_routes" type="fn(&self) -> bool">
  Returns `true` if the router currently has at least one route added.

  ```rust theme={null}
  use axum::{Router, routing::get};

  let router = Router::new();
  assert!(!router.has_routes());

  let router = router.route("/", get(|| async { "Hello" }));
  assert!(router.has_routes());
  ```
</ParamField>
