|
7 | 7 | //! - [Handlers](#handlers)
|
8 | 8 | //! - [Debugging handler type errors](#debugging-handler-type-errors)
|
9 | 9 | //! - [Routing](#routing)
|
10 |
| -//! - [Routing to any `Service`](#routing-to-any-service) |
11 |
| -//! - [Routing to fallible services](#routing-to-fallible-services) |
12 | 10 | //! - [Wildcard routes](#wildcard-routes)
|
13 | 11 | //! - [Nesting routes](#nesting-routes)
|
| 12 | +//! - [Fallback routes](#fallback-routes) |
| 13 | +//! - [Routing to any `Service`](#routing-to-any-service) |
| 14 | +//! - [Routing to fallible services](#routing-to-fallible-services) |
14 | 15 | //! - [Extractors](#extractors)
|
15 | 16 | //! - [Common extractors](#common-extractors)
|
16 | 17 | //! - [Applying multiple extractors](#applying-multiple-extractors)
|
|
143 | 144 | //!
|
144 | 145 | //! # Routing
|
145 | 146 | //!
|
146 |
| -//! Routing between handlers looks like this: |
| 147 | +//! [`Router::route`] is the main way to add routes: |
147 | 148 | //!
|
148 | 149 | //! ```rust,no_run
|
149 | 150 | //! use axum::{
|
|
174 | 175 | //! Routes can also be dynamic like `/users/:id`. See [extractors](#extractors)
|
175 | 176 | //! for more details.
|
176 | 177 | //!
|
177 |
| -//! You can also define routes separately and merge them with [`Router::or`]. |
| 178 | +//! You can also define routes separately and merge them with [`Router::merge`]. |
178 | 179 | //!
|
179 | 180 | //! Routes are not allowed to overlap and will panic if an overlapping route is
|
180 | 181 | //! added. This also means the order in which routes are added doesn't matter.
|
181 | 182 | //!
|
| 183 | +//! ## Wildcard routes |
| 184 | +//! |
| 185 | +//! axum also supports wildcard routes: |
| 186 | +//! |
| 187 | +//! ```rust,no_run |
| 188 | +//! use axum::{ |
| 189 | +//! routing::get, |
| 190 | +//! Router, |
| 191 | +//! }; |
| 192 | +//! |
| 193 | +//! let app = Router::new() |
| 194 | +//! // this matches any request that starts with `/api` |
| 195 | +//! .route("/api/*rest", get(|| async { /* ... */ })); |
| 196 | +//! # async { |
| 197 | +//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); |
| 198 | +//! # }; |
| 199 | +//! ``` |
| 200 | +//! |
| 201 | +//! The matched path can be extracted via [`extract::Path`]: |
| 202 | +//! |
| 203 | +//! ```rust,no_run |
| 204 | +//! use axum::{ |
| 205 | +//! routing::get, |
| 206 | +//! extract::Path, |
| 207 | +//! Router, |
| 208 | +//! }; |
| 209 | +//! |
| 210 | +//! let app = Router::new().route("/api/*rest", get(|Path(rest): Path<String>| async { |
| 211 | +//! // `rest` will be everything after `/api` |
| 212 | +//! })); |
| 213 | +//! # async { |
| 214 | +//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); |
| 215 | +//! # }; |
| 216 | +//! ``` |
| 217 | +//! |
| 218 | +//! ## Nesting routes |
| 219 | +//! |
| 220 | +//! Routes can be nested by calling [`Router::nest`](routing::Router::nest): |
| 221 | +//! |
| 222 | +//! ```rust,no_run |
| 223 | +//! use axum::{ |
| 224 | +//! body::{Body, BoxBody}, |
| 225 | +//! http::Request, |
| 226 | +//! routing::get, |
| 227 | +//! Router, |
| 228 | +//! }; |
| 229 | +//! use tower_http::services::ServeFile; |
| 230 | +//! use http::Response; |
| 231 | +//! |
| 232 | +//! fn api_routes() -> Router { |
| 233 | +//! Router::new() |
| 234 | +//! .route("/users", get(|_: Request<Body>| async { /* ... */ })) |
| 235 | +//! } |
| 236 | +//! |
| 237 | +//! let app = Router::new() |
| 238 | +//! .route("/", get(|_: Request<Body>| async { /* ... */ })) |
| 239 | +//! .nest("/api", api_routes()); |
| 240 | +//! # async { |
| 241 | +//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); |
| 242 | +//! # }; |
| 243 | +//! ``` |
| 244 | +//! |
| 245 | +//! Note that nested routes will not see the orignal request URI but instead |
| 246 | +//! have the matched prefix stripped. This is necessary for services like static |
| 247 | +//! file serving to work. Use [`OriginalUri`] if you need the original request |
| 248 | +//! URI. |
| 249 | +//! |
| 250 | +//! Nested routes are similar to wild card routes. The difference is that |
| 251 | +//! wildcard routes still see the whole URI whereas nested routes will have |
| 252 | +//! the prefix stripped. |
| 253 | +//! |
| 254 | +//! ```rust |
| 255 | +//! use axum::{routing::get, http::Uri, Router}; |
| 256 | +//! |
| 257 | +//! let app = Router::new() |
| 258 | +//! .route("/foo/*rest", get(|uri: Uri| async { |
| 259 | +//! // `uri` will contain `/foo` |
| 260 | +//! })) |
| 261 | +//! .nest("/bar", get(|uri: Uri| async { |
| 262 | +//! // `uri` will _not_ contain `/bar` |
| 263 | +//! })); |
| 264 | +//! # async { |
| 265 | +//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); |
| 266 | +//! # }; |
| 267 | +//! ``` |
| 268 | +//! |
| 269 | +//! ## Fallback routes |
| 270 | +//! |
| 271 | +//! By default axum will respond with an empty `404 Not Found` response to unhandled requests. To |
| 272 | +//! override that you can use [`Router::fallback`]: |
| 273 | +//! |
| 274 | +//! ```rust |
| 275 | +//! use axum::{ |
| 276 | +//! Router, |
| 277 | +//! routing::get, |
| 278 | +//! handler::Handler, |
| 279 | +//! response::IntoResponse, |
| 280 | +//! http::{StatusCode, Uri}, |
| 281 | +//! }; |
| 282 | +//! |
| 283 | +//! async fn fallback(uri: Uri) -> impl IntoResponse { |
| 284 | +//! (StatusCode::NOT_FOUND, format!("No route for {}", uri)) |
| 285 | +//! } |
| 286 | +//! |
| 287 | +//! let app = Router::new() |
| 288 | +//! .route("/foo", get(|| async { /* ... */ })) |
| 289 | +//! .fallback(fallback.into_service()); |
| 290 | +//! # async { |
| 291 | +//! # hyper::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); |
| 292 | +//! # }; |
| 293 | +//! ``` |
| 294 | +//! |
| 295 | +//! See [`Router::fallback`] for more details. |
| 296 | +//! |
182 | 297 | //! ## Routing to any [`Service`]
|
183 | 298 | //!
|
184 | 299 | //! axum also supports routing to general [`Service`]s:
|
|
314 | 429 | //! See ["Error handling"](#error-handling) for more details on [`handle_error`]
|
315 | 430 | //! and error handling in general.
|
316 | 431 | //!
|
317 |
| -//! ## Wildcard routes |
318 |
| -//! |
319 |
| -//! axum also supports wildcard routes: |
320 |
| -//! |
321 |
| -//! ```rust,no_run |
322 |
| -//! use axum::{ |
323 |
| -//! routing::get, |
324 |
| -//! Router, |
325 |
| -//! }; |
326 |
| -//! |
327 |
| -//! let app = Router::new() |
328 |
| -//! // this matches any request that starts with `/api` |
329 |
| -//! .route("/api/*rest", get(|| async { /* ... */ })); |
330 |
| -//! # async { |
331 |
| -//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); |
332 |
| -//! # }; |
333 |
| -//! ``` |
334 |
| -//! |
335 |
| -//! The matched path can be extracted via [`extract::Path`]: |
336 |
| -//! |
337 |
| -//! ```rust,no_run |
338 |
| -//! use axum::{ |
339 |
| -//! routing::get, |
340 |
| -//! extract::Path, |
341 |
| -//! Router, |
342 |
| -//! }; |
343 |
| -//! |
344 |
| -//! let app = Router::new().route("/api/*rest", get(|Path(rest): Path<String>| async { |
345 |
| -//! // `rest` will be everything after `/api` |
346 |
| -//! })); |
347 |
| -//! # async { |
348 |
| -//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); |
349 |
| -//! # }; |
350 |
| -//! ``` |
351 |
| -//! |
352 |
| -//! ## Nesting routes |
353 |
| -//! |
354 |
| -//! Routes can be nested by calling [`Router::nest`](routing::Router::nest): |
355 |
| -//! |
356 |
| -//! ```rust,no_run |
357 |
| -//! use axum::{ |
358 |
| -//! body::{Body, BoxBody}, |
359 |
| -//! http::Request, |
360 |
| -//! routing::get, |
361 |
| -//! Router, |
362 |
| -//! }; |
363 |
| -//! use tower_http::services::ServeFile; |
364 |
| -//! use http::Response; |
365 |
| -//! |
366 |
| -//! fn api_routes() -> Router { |
367 |
| -//! Router::new() |
368 |
| -//! .route("/users", get(|_: Request<Body>| async { /* ... */ })) |
369 |
| -//! } |
370 |
| -//! |
371 |
| -//! let app = Router::new() |
372 |
| -//! .route("/", get(|_: Request<Body>| async { /* ... */ })) |
373 |
| -//! .nest("/api", api_routes()); |
374 |
| -//! # async { |
375 |
| -//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); |
376 |
| -//! # }; |
377 |
| -//! ``` |
378 |
| -//! |
379 |
| -//! Note that nested routes will not see the orignal request URI but instead |
380 |
| -//! have the matched prefix stripped. This is necessary for services like static |
381 |
| -//! file serving to work. Use [`OriginalUri`] if you need the original request |
382 |
| -//! URI. |
383 |
| -//! |
384 |
| -//! Nested routes are similar to wild card routes. The difference is that |
385 |
| -//! wildcard routes still see the whole URI whereas nested routes will have |
386 |
| -//! the prefix stripped. |
387 |
| -//! |
388 |
| -//! ```rust |
389 |
| -//! use axum::{routing::get, http::Uri, Router}; |
390 |
| -//! |
391 |
| -//! let app = Router::new() |
392 |
| -//! .route("/foo/*rest", get(|uri: Uri| async { |
393 |
| -//! // `uri` will contain `/foo` |
394 |
| -//! })) |
395 |
| -//! .nest("/bar", get(|uri: Uri| async { |
396 |
| -//! // `uri` will _not_ contain `/bar` |
397 |
| -//! })); |
398 |
| -//! # async { |
399 |
| -//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); |
400 |
| -//! # }; |
401 |
| -//! ``` |
402 |
| -//! |
403 | 432 | //! # Extractors
|
404 | 433 | //!
|
405 | 434 | //! An extractor is a type that implements [`FromRequest`]. Extractors is how
|
|
862 | 891 | //! Note that [`Router::layer`] applies the middleware to all previously added
|
863 | 892 | //! routes, of that particular `Router`. If you need multiple groups of routes
|
864 | 893 | //! with different middleware build them separately and combine them with
|
865 |
| -//! [`Router::or`]: |
| 894 | +//! [`Router::merge`]: |
866 | 895 | //!
|
867 | 896 | //! ```rust,no_run
|
868 | 897 | //! use axum::{
|
|
883 | 912 | //! .route("/requires-auth", get(handler))
|
884 | 913 | //! .layer(MyAuthLayer::new());
|
885 | 914 | //!
|
886 |
| -//! let app = foo.or(bar); |
| 915 | +//! let app = foo.merge(bar); |
887 | 916 | //! # async {
|
888 | 917 | //! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
889 | 918 | //! # };
|
|
1148 | 1177 | //! [`IntoResponse`]: crate::response::IntoResponse
|
1149 | 1178 | //! [`Timeout`]: tower::timeout::Timeout
|
1150 | 1179 | //! [examples]: https://github.com/tokio-rs/axum/tree/main/examples
|
1151 |
| -//! [`Router::or`]: crate::routing::Router::or |
| 1180 | +//! [`Router::merge`]: crate::routing::Router::merge |
1152 | 1181 | //! [`axum::Server`]: hyper::server::Server
|
1153 | 1182 | //! [`OriginalUri`]: crate::extract::OriginalUri
|
1154 | 1183 | //! [`Service`]: tower::Service
|
|
0 commit comments