> ## 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.

# Routing

> Learn how to define routes and compose routers in Axum

Routing is the process of matching incoming HTTP requests to handler functions based on the request's path and method. Axum provides a powerful and flexible routing system through the `Router` type.

## Creating a router

Create a new router using `Router::new()`:

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

let app = Router::new();
```

A newly created router will respond with `404 Not Found` to all requests until you add routes.

## Adding routes

Use the `route` method to add routes to your router. Each route consists of a path pattern and a `MethodRouter` that defines which HTTP methods are handled:

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

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

## HTTP method routing

Axum provides convenience functions for each HTTP method:

<Tabs>
  <Tab title="GET">
    ```rust theme={null}
    use axum::{Router, routing::get};

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

    async fn list_users() -> &'static str {
        "User list"
    }
    ```

    <Note>
      `GET` routes also handle `HEAD` requests automatically, but with the response body removed.
    </Note>
  </Tab>

  <Tab title="POST">
    ```rust theme={null}
    use axum::{Router, routing::post};

    let app = Router::new()
        .route("/users", post(create_user));

    async fn create_user() -> &'static str {
        "User created"
    }
    ```
  </Tab>

  <Tab title="PUT/PATCH">
    ```rust theme={null}
    use axum::{Router, routing::{put, patch}};

    let app = Router::new()
        .route("/users/:id", put(update_user))
        .route("/users/:id", patch(partial_update));

    async fn update_user() -> &'static str {
        "User updated"
    }

    async fn partial_update() -> &'static str {
        "User partially updated"
    }
    ```
  </Tab>

  <Tab title="DELETE">
    ```rust theme={null}
    use axum::{Router, routing::delete};

    let app = Router::new()
        .route("/users/:id", delete(delete_user));

    async fn delete_user() -> &'static str {
        "User deleted"
    }
    ```
  </Tab>
</Tabs>

## Path patterns

Axum supports dynamic path segments using named parameters:

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

// Single parameter
let app = Router::new()
    .route("/users/:id", get(get_user));

async fn get_user(Path(id): Path<String>) -> String {
    format!("User ID: {}", id)
}

// Multiple parameters
let app = Router::new()
    .route("/users/:user_id/team/:team_id", get(get_team));

async fn get_team(Path((user_id, team_id)): Path<(String, String)>) -> String {
    format!("User {} in team {}", user_id, team_id)
}
```

### Wildcard captures

Capture the rest of the path with wildcard parameters:

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

let app = Router::new()
    .route("/files/*path", get(serve_file));

async fn serve_file(Path(path): Path<String>) -> String {
    format!("Serving file: {}", path)
}
```

## Combining routes

### Chaining routes

Chain multiple `route` calls to add multiple routes:

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

let app = Router::new()
    .route("/", get(root))
    .route("/users", get(list_users).post(create_user))
    .route("/users/:id", get(get_user).delete(delete_user));
```

### Merging routers

Combine multiple routers with `merge`:

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

let user_routes = Router::new()
    .route("/users", get(list_users))
    .route("/users/:id", get(get_user));

let post_routes = Router::new()
    .route("/posts", get(list_posts))
    .route("/posts/:id", get(get_post));

let app = Router::new()
    .merge(user_routes)
    .merge(post_routes);
```

### Nesting routers

Nest a router under a path prefix:

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

let api_routes = Router::new()
    .route("/users", get(list_users))
    .route("/posts", get(list_posts));

let app = Router::new()
    .nest("/api", api_routes);

// Routes are now available at:
// - /api/users
// - /api/posts
```

<Warning>
  Nesting at the root (`"/"`) is not supported. Use `merge` instead.
</Warning>

## Fallback handlers

Handle requests that don't match any route:

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

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

## Route services

For more control, you can route to any Tower `Service`:

```rust theme={null}
use axum::{Router, routing::get_service};
use tower::service_fn;
use http::Response;
use std::convert::Infallible;

let service = tower::service_fn(|_req| async {
    Ok::<_, Infallible>(Response::new(axum::body::Body::empty()))
});

let app = Router::new()
    .route("/", get_service(service));
```

## Placeholder handlers

<Accordion title="Understanding placeholder handlers">
  You can pass types that implement `IntoResponse` directly as handlers:

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

  let app = Router::new()
      // Return a fixed string
      .route("/", get("Hello, World!"))
      // Return mock data
      .route("/users", get((
          StatusCode::OK,
          Json(json!({ "id": 1, "name": "alice" })),
      )));
  ```
</Accordion>

## Next steps

<CardGroup cols={2}>
  <Card title="Handlers" icon="function" href="/concepts/handlers">
    Learn about handler functions and their signatures
  </Card>

  <Card title="State" icon="database" href="/concepts/state">
    Share state across handlers using `with_state`
  </Card>
</CardGroup>
