summaryrefslogtreecommitdiff
path: root/vendor/axum/src/docs/routing/fallback.md
blob: a864b7a45d7fa5151490a428943bacd283474c17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Add a fallback [`Handler`] to the router.

This service will be called if no routes matches the incoming request.

```rust
use axum::{
    Router,
    routing::get,
    handler::Handler,
    response::IntoResponse,
    http::{StatusCode, Uri},
};

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

async fn fallback(uri: Uri) -> (StatusCode, String) {
    (StatusCode::NOT_FOUND, format!("No route for {uri}"))
}
# let _: Router = app;
```

Fallbacks only apply to routes that aren't matched by anything in the
router. If a handler is matched by a request but returns 404 the
fallback is not called. Note that this applies to [`MethodRouter`]s too: if the
request hits a valid path but the [`MethodRouter`] does not have an appropriate
method handler installed, the fallback is not called (use
[`MethodRouter::fallback`] for this purpose instead).


# Handling all requests without other routes

Using `Router::new().fallback(...)` to accept all request regardless of path or
method, if you don't have other routes, isn't optimal:

```rust
use axum::Router;

async fn handler() {}

let app = Router::new().fallback(handler);

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

Running the handler directly is faster since it avoids the overhead of routing:

```rust
use axum::handler::HandlerWithoutStateExt;

async fn handler() {}

# async {
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, handler.into_make_service()).await.unwrap();
# };
```