mirror of
https://github.com/tokio-rs/axum.git
synced 2024-11-21 22:56:46 +01:00
Replace route
with Router::new().route()
(#215)
This way there is now only one way to create a router: ```rust use axum::{Router, handler::get}; let app = Router::new() .route("/foo", get(handler)) .route("/foo", get(handler)); ``` `nest` was changed in the same way: ```rust use axum::Router; let app = Router::new().nest("/foo", service); ```
This commit is contained in:
parent
97b53768ba
commit
ca4d9a2bb9
49 changed files with 652 additions and 625 deletions
|
@ -9,8 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
- Overall compile time improvements. If you're having issues with compile time
|
||||
please file an issue!
|
||||
- Remove `prelude`. Explicit imports are now required.
|
||||
- Add dedicated `Router` to replace the `RoutingDsl` trait
|
||||
- Remove `prelude`. Explicit imports are now required ([#195](https://github.com/tokio-rs/axum/pull/195))
|
||||
- Add dedicated `Router` to replace the `RoutingDsl` trait ([#214](https://github.com/tokio-rs/axum/pull/214))
|
||||
- Replace `axum::route(...)` with `axum::Router::new().route(...)`. This means
|
||||
there is now only one way to create a new router. Same goes for
|
||||
`axum::routing::nest`. ([#215](https://github.com/tokio-rs/axum/pull/215))
|
||||
- Make `FromRequest` default to being generic over `body::Body` ([#146](https://github.com/tokio-rs/axum/pull/146))
|
||||
- Implement `std::error::Error` for all rejections ([#153](https://github.com/tokio-rs/axum/pull/153))
|
||||
- Add `Router::or` for combining routes ([#108](https://github.com/tokio-rs/axum/pull/108))
|
||||
|
|
|
@ -3,7 +3,7 @@ mod starwars;
|
|||
use async_graphql::http::{playground_source, GraphQLPlaygroundConfig};
|
||||
use async_graphql::{EmptyMutation, EmptySubscription, Request, Response, Schema};
|
||||
use axum::response::IntoResponse;
|
||||
use axum::{extract::Extension, handler::get, response::Html, route, AddExtensionLayer, Json};
|
||||
use axum::{extract::Extension, handler::get, response::Html, AddExtensionLayer, Json, Router};
|
||||
use starwars::{QueryRoot, StarWars, StarWarsSchema};
|
||||
|
||||
async fn graphql_handler(schema: Extension<StarWarsSchema>, req: Json<Request>) -> Json<Response> {
|
||||
|
@ -20,7 +20,8 @@ async fn main() {
|
|||
.data(StarWars::new())
|
||||
.finish();
|
||||
|
||||
let app = route("/", get(graphql_playground).post(graphql_handler))
|
||||
let app = Router::new()
|
||||
.route("/", get(graphql_playground).post(graphql_handler))
|
||||
.layer(AddExtensionLayer::new(schema));
|
||||
|
||||
println!("Playground: http://localhost:3000");
|
||||
|
|
|
@ -10,8 +10,8 @@ use axum::extract::ws::{Message, WebSocket, WebSocketUpgrade};
|
|||
use axum::extract::Extension;
|
||||
use axum::handler::get;
|
||||
use axum::response::{Html, IntoResponse};
|
||||
use axum::route;
|
||||
use axum::AddExtensionLayer;
|
||||
use axum::Router;
|
||||
use futures::{sink::SinkExt, stream::StreamExt};
|
||||
use std::collections::HashSet;
|
||||
use std::net::SocketAddr;
|
||||
|
@ -31,7 +31,8 @@ async fn main() {
|
|||
|
||||
let app_state = Arc::new(AppState { user_set, tx });
|
||||
|
||||
let app = route("/", get(index))
|
||||
let app = Router::new()
|
||||
.route("/", get(index))
|
||||
.route("/websocket", get(websocket_handler))
|
||||
.layer(AddExtensionLayer::new(app_state));
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use axum::{
|
|||
handler::{get, post},
|
||||
http::{Response, StatusCode},
|
||||
response::IntoResponse,
|
||||
route, AddExtensionLayer, Json,
|
||||
AddExtensionLayer, Json, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
|
@ -37,7 +37,8 @@ async fn main() {
|
|||
let user_repo = Arc::new(ExampleUserRepo) as DynUserRepo;
|
||||
|
||||
// Build our application with some routes
|
||||
let app = route("/users/:id", get(users_show))
|
||||
let app = Router::new()
|
||||
.route("/users/:id", get(users_show))
|
||||
.route("/users", post(users_create))
|
||||
// Add our `user_repo` to all request's extensions so handlers can access
|
||||
// it.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! cargo run -p example-form
|
||||
//! ```
|
||||
|
||||
use axum::{extract::Form, handler::get, response::Html, route};
|
||||
use axum::{extract::Form, handler::get, response::Html, Router};
|
||||
use serde::Deserialize;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
|
@ -17,7 +17,7 @@ async fn main() {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
// build our application with some routes
|
||||
let app = route("/", get(show_form).post(accept_form));
|
||||
let app = Router::new().route("/", get(show_form).post(accept_form));
|
||||
|
||||
// run it with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
|
|
|
@ -9,7 +9,7 @@ use axum::{
|
|||
handler::get,
|
||||
http::{Response, StatusCode},
|
||||
response::Html,
|
||||
route,
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
use tower::util::MapResponseLayer;
|
||||
|
@ -23,7 +23,8 @@ async fn main() {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
// build our application with a route
|
||||
let app = route("/", get(handler))
|
||||
let app = Router::new()
|
||||
.route("/", get(handler))
|
||||
// make sure this is added as the very last thing
|
||||
.layer(MapResponseLayer::new(map_404));
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
//! cargo run -p example-hello-world
|
||||
//! ```
|
||||
|
||||
use axum::{handler::get, route};
|
||||
use axum::{handler::get, Router};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// build our application with a route
|
||||
let app = route("/foo", get(handler));
|
||||
let app = Router::new().route("/", get(handler));
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
|
|
|
@ -12,8 +12,8 @@ use axum::{
|
|||
handler::{delete, get, Handler},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
route,
|
||||
routing::{BoxRoute, Router},
|
||||
routing::BoxRoute,
|
||||
Router,
|
||||
};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
|
@ -38,29 +38,30 @@ async fn main() {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Build our application by composing routes
|
||||
let app = route(
|
||||
"/:key",
|
||||
// Add compression to `kv_get`
|
||||
get(kv_get.layer(CompressionLayer::new()))
|
||||
// But don't compress `kv_set`
|
||||
.post(kv_set),
|
||||
)
|
||||
.route("/keys", get(list_keys))
|
||||
// Nest our admin routes under `/admin`
|
||||
.nest("/admin", admin_routes())
|
||||
// Add middleware to all routes
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
.load_shed()
|
||||
.concurrency_limit(1024)
|
||||
.timeout(Duration::from_secs(10))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.layer(AddExtensionLayer::new(SharedState::default()))
|
||||
.into_inner(),
|
||||
)
|
||||
// Handle errors from middleware
|
||||
.handle_error(handle_error)
|
||||
.check_infallible();
|
||||
let app = Router::new()
|
||||
.route(
|
||||
"/:key",
|
||||
// Add compression to `kv_get`
|
||||
get(kv_get.layer(CompressionLayer::new()))
|
||||
// But don't compress `kv_set`
|
||||
.post(kv_set),
|
||||
)
|
||||
.route("/keys", get(list_keys))
|
||||
// Nest our admin routes under `/admin`
|
||||
.nest("/admin", admin_routes())
|
||||
// Add middleware to all routes
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
.load_shed()
|
||||
.concurrency_limit(1024)
|
||||
.timeout(Duration::from_secs(10))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.layer(AddExtensionLayer::new(SharedState::default()))
|
||||
.into_inner(),
|
||||
)
|
||||
// Handle errors from middleware
|
||||
.handle_error(handle_error)
|
||||
.check_infallible();
|
||||
|
||||
// Run our app with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
|
@ -117,7 +118,8 @@ fn admin_routes() -> Router<BoxRoute> {
|
|||
state.write().unwrap().db.remove(&key);
|
||||
}
|
||||
|
||||
route("/keys", delete(delete_all_keys))
|
||||
Router::new()
|
||||
.route("/keys", delete(delete_all_keys))
|
||||
.route("/key/:key", delete(remove_key))
|
||||
// Require bearer auth for all admin routes
|
||||
.layer(RequireAuthorizationLayer::bearer("secret-token"))
|
||||
|
|
|
@ -8,7 +8,7 @@ use axum::{
|
|||
extract::{ContentLengthLimit, Multipart},
|
||||
handler::get,
|
||||
response::Html,
|
||||
route,
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
|
@ -21,7 +21,8 @@ async fn main() {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
// build our application with some routes
|
||||
let app = route("/", get(show_form).post(accept_form))
|
||||
let app = Router::new()
|
||||
.route("/", get(show_form).post(accept_form))
|
||||
.layer(tower_http::trace::TraceLayer::new_for_http());
|
||||
|
||||
// run it with hyper
|
||||
|
|
|
@ -14,7 +14,7 @@ use axum::{
|
|||
handler::get,
|
||||
http::{header::SET_COOKIE, HeaderMap, Response},
|
||||
response::{IntoResponse, Redirect},
|
||||
route, AddExtensionLayer,
|
||||
AddExtensionLayer, Router,
|
||||
};
|
||||
use oauth2::{
|
||||
basic::BasicClient, reqwest::async_http_client, AuthUrl, AuthorizationCode, ClientId,
|
||||
|
@ -42,8 +42,11 @@ async fn main() {
|
|||
|
||||
// `MemoryStore` just used as an example. Don't use this in production.
|
||||
let store = MemoryStore::new();
|
||||
|
||||
let oauth_client = oauth_client();
|
||||
let app = route("/", get(index))
|
||||
|
||||
let app = Router::new()
|
||||
.route("/", get(index))
|
||||
.route("/auth/discord", get(discord_auth))
|
||||
.route("/auth/authorized", get(login_authorized))
|
||||
.route("/protected", get(protected))
|
||||
|
|
|
@ -15,7 +15,7 @@ use axum::{
|
|||
StatusCode,
|
||||
},
|
||||
response::IntoResponse,
|
||||
route, AddExtensionLayer,
|
||||
AddExtensionLayer, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::SocketAddr;
|
||||
|
@ -32,7 +32,9 @@ async fn main() {
|
|||
// `MemoryStore` just used as an example. Don't use this in production.
|
||||
let store = MemoryStore::new();
|
||||
|
||||
let app = route("/", get(handler)).layer(AddExtensionLayer::new(store));
|
||||
let app = Router::new()
|
||||
.route("/", get(handler))
|
||||
.layer(AddExtensionLayer::new(store));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
|
|
|
@ -9,7 +9,7 @@ use axum::{
|
|||
handler::get,
|
||||
http::StatusCode,
|
||||
response::sse::{sse, Event, Sse},
|
||||
routing::nest,
|
||||
Router,
|
||||
};
|
||||
use futures::stream::{self, Stream};
|
||||
use std::{convert::Infallible, net::SocketAddr, time::Duration};
|
||||
|
@ -35,7 +35,8 @@ async fn main() {
|
|||
});
|
||||
|
||||
// build our application with a route
|
||||
let app = nest("/", static_files_service)
|
||||
let app = Router::new()
|
||||
.nest("/", static_files_service)
|
||||
.route("/sse", get(sse_handler))
|
||||
.layer(TraceLayer::new_for_http());
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
//! cargo run -p example-static-file-server
|
||||
//! ```
|
||||
|
||||
use axum::{http::StatusCode, routing::nest};
|
||||
use std::net::SocketAddr;
|
||||
use axum::{http::StatusCode, service, Router};
|
||||
use std::{convert::Infallible, net::SocketAddr};
|
||||
use tower_http::{services::ServeDir, trace::TraceLayer};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -19,16 +19,17 @@ async fn main() {
|
|||
}
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let app = nest(
|
||||
"/static",
|
||||
axum::service::get(ServeDir::new(".")).handle_error(|error: std::io::Error| {
|
||||
Ok::<_, std::convert::Infallible>((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Unhandled internal error: {}", error),
|
||||
))
|
||||
}),
|
||||
)
|
||||
.layer(TraceLayer::new_for_http());
|
||||
let app = Router::new()
|
||||
.nest(
|
||||
"/static",
|
||||
service::get(ServeDir::new(".")).handle_error(|error: std::io::Error| {
|
||||
Ok::<_, Infallible>((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Unhandled internal error: {}", error),
|
||||
))
|
||||
}),
|
||||
)
|
||||
.layer(TraceLayer::new_for_http());
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
|
|
|
@ -11,7 +11,7 @@ use axum::{
|
|||
handler::get,
|
||||
http::{Response, StatusCode},
|
||||
response::{Html, IntoResponse},
|
||||
route,
|
||||
Router,
|
||||
};
|
||||
use std::{convert::Infallible, net::SocketAddr};
|
||||
|
||||
|
@ -24,7 +24,7 @@ async fn main() {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
// build our application with some routes
|
||||
let app = route("/greet/:name", get(greet));
|
||||
let app = Router::new().route("/greet/:name", get(greet));
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
|
||||
use axum::{
|
||||
handler::{get, post},
|
||||
route,
|
||||
routing::{BoxRoute, Router},
|
||||
Json,
|
||||
routing::BoxRoute,
|
||||
Json, Router,
|
||||
};
|
||||
use tower_http::trace::TraceLayer;
|
||||
|
||||
|
@ -34,7 +33,8 @@ async fn main() {
|
|||
/// without having to create an HTTP server.
|
||||
#[allow(dead_code)]
|
||||
fn app() -> Router<BoxRoute> {
|
||||
route("/", get(|| async { "Hello, World!" }))
|
||||
Router::new()
|
||||
.route("/", get(|| async { "Hello, World!" }))
|
||||
.route(
|
||||
"/json",
|
||||
post(|payload: Json<serde_json::Value>| async move {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! cargo run -p example-tls-rustls
|
||||
//! ```
|
||||
|
||||
use axum::{handler::get, route};
|
||||
use axum::{handler::get, Router};
|
||||
use hyper::server::conn::Http;
|
||||
use std::{fs::File, io::BufReader, sync::Arc};
|
||||
use tokio::net::TcpListener;
|
||||
|
@ -31,7 +31,7 @@ async fn main() {
|
|||
let acceptor = TlsAcceptor::from(rustls_config);
|
||||
let listener = TcpListener::bind("127.0.0.1:3000").await.unwrap();
|
||||
|
||||
let app = route("/", get(handler));
|
||||
let app = Router::new().route("/", get(handler));
|
||||
|
||||
loop {
|
||||
let (stream, _addr) = listener.accept().await.unwrap();
|
||||
|
|
|
@ -18,7 +18,7 @@ use axum::{
|
|||
handler::{get, patch},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
route, Json,
|
||||
Json, Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
|
@ -43,7 +43,8 @@ async fn main() {
|
|||
let db = Db::default();
|
||||
|
||||
// Compose the routes
|
||||
let app = route("/todos", get(todos_index).post(todos_create))
|
||||
let app = Router::new()
|
||||
.route("/todos", get(todos_index).post(todos_create))
|
||||
.route("/todos/:id", patch(todos_update).delete(todos_delete))
|
||||
// Add middleware to all routes
|
||||
.layer(
|
||||
|
@ -53,7 +54,6 @@ async fn main() {
|
|||
.layer(AddExtensionLayer::new(db))
|
||||
.into_inner(),
|
||||
)
|
||||
// If the timeout fails, map the error to a response
|
||||
.handle_error(|error: BoxError| {
|
||||
let result = if error.is::<tower::timeout::error::Elapsed>() {
|
||||
Ok(StatusCode::REQUEST_TIMEOUT)
|
||||
|
|
|
@ -9,7 +9,7 @@ use axum::{
|
|||
extract::{Extension, FromRequest, RequestParts},
|
||||
handler::get,
|
||||
http::StatusCode,
|
||||
route, AddExtensionLayer,
|
||||
AddExtensionLayer, Router,
|
||||
};
|
||||
use bb8::{Pool, PooledConnection};
|
||||
use bb8_postgres::PostgresConnectionManager;
|
||||
|
@ -31,11 +31,12 @@ async fn main() {
|
|||
let pool = Pool::builder().build(manager).await.unwrap();
|
||||
|
||||
// build our application with some routes
|
||||
let app = route(
|
||||
"/",
|
||||
get(using_connection_pool_extractor).post(using_connection_extractor),
|
||||
)
|
||||
.layer(AddExtensionLayer::new(pool));
|
||||
let app = Router::new()
|
||||
.route(
|
||||
"/",
|
||||
get(using_connection_pool_extractor).post(using_connection_extractor),
|
||||
)
|
||||
.layer(AddExtensionLayer::new(pool));
|
||||
|
||||
// run it with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! cargo run -p example-tracing-aka-logging
|
||||
//! ```
|
||||
|
||||
use axum::{handler::get, response::Html, route};
|
||||
use axum::{handler::get, response::Html, Router};
|
||||
use std::net::SocketAddr;
|
||||
use tower_http::trace::TraceLayer;
|
||||
|
||||
|
@ -20,7 +20,8 @@ async fn main() {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
// build our application with a route
|
||||
let app = route("/", get(handler))
|
||||
let app = Router::new()
|
||||
.route("/", get(handler))
|
||||
// `TraceLayer` is provided by tower-http so you have to add that as a dependency.
|
||||
// It provides good defaults but is also very customizable.
|
||||
// See https://docs.rs/tower-http/0.1.1/tower_http/trace/index.html for more details.
|
||||
|
|
|
@ -9,7 +9,7 @@ use axum::{
|
|||
extract::connect_info::{self, ConnectInfo},
|
||||
handler::get,
|
||||
http::{Method, Request, StatusCode, Uri},
|
||||
route,
|
||||
Router,
|
||||
};
|
||||
use futures::ready;
|
||||
use hyper::{
|
||||
|
@ -53,7 +53,7 @@ async fn main() {
|
|||
|
||||
let uds = UnixListener::bind(path.clone()).unwrap();
|
||||
tokio::spawn(async {
|
||||
let app = route("/", get(handler));
|
||||
let app = Router::new().route("/", get(handler));
|
||||
|
||||
axum::Server::builder(ServerAccept { uds })
|
||||
.serve(app.into_make_service_with_connect_info::<UdsConnectInfo, _>())
|
||||
|
|
|
@ -11,7 +11,7 @@ use axum::{
|
|||
handler::get,
|
||||
http::{Response, StatusCode},
|
||||
response::IntoResponse,
|
||||
route,
|
||||
Router,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::net::SocketAddr;
|
||||
|
@ -25,7 +25,7 @@ async fn main() {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
// build our application with some routes
|
||||
let app = route("/:version/foo", get(handler));
|
||||
let app = Router::new().route("/:version/foo", get(handler));
|
||||
|
||||
// run it
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
|
|
|
@ -14,7 +14,7 @@ use axum::{
|
|||
handler::get,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::nest,
|
||||
Router,
|
||||
};
|
||||
use std::net::SocketAddr;
|
||||
use tower_http::{
|
||||
|
@ -31,25 +31,27 @@ async fn main() {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
// build our application with some routes
|
||||
let app = nest(
|
||||
"/",
|
||||
axum::service::get(
|
||||
ServeDir::new("examples/websockets/assets").append_index_html_on_directories(true),
|
||||
let app = Router::new()
|
||||
.nest(
|
||||
"/",
|
||||
axum::service::get(
|
||||
ServeDir::new("examples/websockets/assets").append_index_html_on_directories(true),
|
||||
)
|
||||
.handle_error(|error: std::io::Error| {
|
||||
Ok::<_, std::convert::Infallible>((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Unhandled internal error: {}", error),
|
||||
))
|
||||
}),
|
||||
)
|
||||
.handle_error(|error: std::io::Error| {
|
||||
Ok::<_, std::convert::Infallible>((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Unhandled internal error: {}", error),
|
||||
))
|
||||
}),
|
||||
)
|
||||
// routes are matched from bottom to top, so we have to put `nest` at the
|
||||
// top since it matches all routes
|
||||
.route("/ws", get(ws_handler))
|
||||
// logging so we can see whats going on
|
||||
.layer(
|
||||
TraceLayer::new_for_http().make_span_with(DefaultMakeSpan::default().include_headers(true)),
|
||||
);
|
||||
// routes are matched from bottom to top, so we have to put `nest` at the
|
||||
// top since it matches all routes
|
||||
.route("/ws", get(ws_handler))
|
||||
// logging so we can see whats going on
|
||||
.layer(
|
||||
TraceLayer::new_for_http()
|
||||
.make_span_with(DefaultMakeSpan::default().include_headers(true)),
|
||||
);
|
||||
|
||||
// run it with hyper
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
|
|
|
@ -131,7 +131,7 @@ where
|
|||
mod tests {
|
||||
use super::*;
|
||||
use crate::Server;
|
||||
use crate::{handler::get, route};
|
||||
use crate::{handler::get, Router};
|
||||
use std::net::{SocketAddr, TcpListener};
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -145,7 +145,7 @@ mod tests {
|
|||
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
tokio::spawn(async move {
|
||||
let app = route("/", get(handler));
|
||||
let app = Router::new().route("/", get(handler));
|
||||
let server = Server::from_tcp(listener)
|
||||
.unwrap()
|
||||
.serve(app.into_make_service_with_connect_info::<SocketAddr, _>());
|
||||
|
@ -187,7 +187,7 @@ mod tests {
|
|||
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
tokio::spawn(async move {
|
||||
let app = route("/", get(handler));
|
||||
let app = Router::new().route("/", get(handler));
|
||||
let server = Server::from_tcp(listener)
|
||||
.unwrap()
|
||||
.serve(app.into_make_service_with_connect_info::<MyConnectInfo, _>());
|
||||
|
|
|
@ -12,14 +12,14 @@ use std::ops::Deref;
|
|||
/// use axum::{
|
||||
/// extract::ContentLengthLimit,
|
||||
/// handler::post,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
///
|
||||
/// async fn handler(body: ContentLengthLimit<String, 1024>) {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/", post(handler));
|
||||
/// let app = Router::new().route("/", post(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
|
@ -13,7 +13,7 @@ use std::ops::Deref;
|
|||
/// AddExtensionLayer,
|
||||
/// extract::Extension,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use std::sync::Arc;
|
||||
///
|
||||
|
@ -28,7 +28,7 @@ use std::ops::Deref;
|
|||
///
|
||||
/// let state = Arc::new(State { /* ... */ });
|
||||
///
|
||||
/// let app = route("/", get(handler))
|
||||
/// let app = Router::new().route("/", get(handler))
|
||||
/// // Add middleware that inserts the state into all incoming request's
|
||||
/// // extensions.
|
||||
/// .layer(AddExtensionLayer::new(state));
|
||||
|
|
|
@ -37,7 +37,7 @@ use tower::{BoxError, Layer, Service};
|
|||
/// use axum::{
|
||||
/// extract::{extractor_middleware, FromRequest, RequestParts},
|
||||
/// handler::{get, post},
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use http::StatusCode;
|
||||
/// use async_trait::async_trait;
|
||||
|
@ -76,7 +76,8 @@ use tower::{BoxError, Layer, Service};
|
|||
/// // If we get here the request has been authorized
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/", get(handler))
|
||||
/// let app = Router::new()
|
||||
/// .route("/", get(handler))
|
||||
/// .route("/foo", post(other_handler))
|
||||
/// // The extractor will run before all routes
|
||||
/// .layer(extractor_middleware::<RequireAuth>());
|
||||
|
|
|
@ -17,7 +17,7 @@ use tower::BoxError;
|
|||
/// use axum::{
|
||||
/// extract::Form,
|
||||
/// handler::post,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use serde::Deserialize;
|
||||
///
|
||||
|
@ -33,7 +33,7 @@ use tower::BoxError;
|
|||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/sign_up", post(accept_form));
|
||||
/// let app = Router::new().route("/sign_up", post(accept_form));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
//! use axum::{
|
||||
//! Json,
|
||||
//! handler::{post, Handler},
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use serde::Deserialize;
|
||||
//!
|
||||
|
@ -27,7 +27,7 @@
|
|||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! let app = route("/users", post(create_user));
|
||||
//! let app = Router::new().route("/users", post(create_user));
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
|
@ -42,7 +42,7 @@
|
|||
//! async_trait,
|
||||
//! extract::{FromRequest, RequestParts},
|
||||
//! handler::get,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use http::{StatusCode, header::{HeaderValue, USER_AGENT}};
|
||||
//!
|
||||
|
@ -72,7 +72,7 @@
|
|||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! let app = route("/foo", get(handler));
|
||||
//! let app = Router::new().route("/foo", get(handler));
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
|
@ -86,7 +86,7 @@
|
|||
//! use axum::{
|
||||
//! extract::{Path, Query},
|
||||
//! handler::get,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use std::collections::HashMap;
|
||||
//!
|
||||
|
@ -101,7 +101,7 @@
|
|||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! let app = route("/foo", get(handler));
|
||||
//! let app = Router::new().route("/foo", get(handler));
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
|
@ -118,7 +118,7 @@
|
|||
//! use axum::{
|
||||
//! extract::Json,
|
||||
//! handler::post,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use serde_json::Value;
|
||||
//!
|
||||
|
@ -130,7 +130,7 @@
|
|||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! let app = route("/users", post(create_user));
|
||||
//! let app = Router::new().route("/users", post(create_user));
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
|
@ -143,7 +143,7 @@
|
|||
//! use axum::{
|
||||
//! extract::{Json, rejection::JsonRejection},
|
||||
//! handler::post,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use serde_json::Value;
|
||||
//!
|
||||
|
@ -169,7 +169,7 @@
|
|||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! let app = route("/users", post(create_user));
|
||||
//! let app = Router::new().route("/users", post(create_user));
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
|
@ -184,7 +184,7 @@
|
|||
//! use axum::{
|
||||
//! extract::Json,
|
||||
//! handler::post,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use serde_json::Value;
|
||||
//!
|
||||
|
@ -192,7 +192,7 @@
|
|||
//! // `value` is of type `Value`
|
||||
//! }
|
||||
//!
|
||||
//! let app = route("/users", post(create_user));
|
||||
//! let app = Router::new().route("/users", post(create_user));
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
|
@ -217,7 +217,7 @@
|
|||
//! body::Body,
|
||||
//! handler::get,
|
||||
//! http::{header::HeaderMap, Request},
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//!
|
||||
//! struct MyBody<B>(B);
|
||||
|
@ -244,10 +244,10 @@
|
|||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! let app =
|
||||
//! // `String` works directly with any body type
|
||||
//! route(
|
||||
//! let app = Router::new()
|
||||
//! .route(
|
||||
//! "/string",
|
||||
//! // `String` works directly with any body type
|
||||
//! get(|_: String| async {})
|
||||
//! )
|
||||
//! .route(
|
||||
|
|
|
@ -23,7 +23,7 @@ use tower::BoxError;
|
|||
/// use axum::{
|
||||
/// extract::Multipart,
|
||||
/// handler::post,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use futures::stream::StreamExt;
|
||||
///
|
||||
|
@ -36,7 +36,7 @@ use tower::BoxError;
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/upload", post(upload));
|
||||
/// let app = Router::new().route("/upload", post(upload));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
|
@ -14,7 +14,7 @@ use std::ops::{Deref, DerefMut};
|
|||
/// use axum::{
|
||||
/// extract::Path,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use uuid::Uuid;
|
||||
///
|
||||
|
@ -24,7 +24,7 @@ use std::ops::{Deref, DerefMut};
|
|||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/users/:user_id/team/:team_id", get(users_teams_show));
|
||||
/// let app = Router::new().route("/users/:user_id/team/:team_id", get(users_teams_show));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -36,7 +36,7 @@ use std::ops::{Deref, DerefMut};
|
|||
/// use axum::{
|
||||
/// extract::Path,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use uuid::Uuid;
|
||||
///
|
||||
|
@ -44,7 +44,7 @@ use std::ops::{Deref, DerefMut};
|
|||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/users/:user_id", get(user_info));
|
||||
/// let app = Router::new().route("/users/:user_id", get(user_info));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -57,7 +57,7 @@ use std::ops::{Deref, DerefMut};
|
|||
/// use axum::{
|
||||
/// extract::Path,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use serde::Deserialize;
|
||||
/// use uuid::Uuid;
|
||||
|
@ -74,7 +74,7 @@ use std::ops::{Deref, DerefMut};
|
|||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/users/:user_id/team/:team_id", get(users_teams_show));
|
||||
/// let app = Router::new().route("/users/:user_id/team/:team_id", get(users_teams_show));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
|
@ -13,7 +13,7 @@ use std::ops::Deref;
|
|||
/// use axum::{
|
||||
/// extract::Query,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use serde::Deserialize;
|
||||
///
|
||||
|
@ -31,7 +31,7 @@ use std::ops::Deref;
|
|||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/list_things", get(list_things));
|
||||
/// let app = Router::new().route("/list_things", get(list_things));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::convert::Infallible;
|
|||
/// use axum::{
|
||||
/// extract::RawQuery,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use futures::StreamExt;
|
||||
///
|
||||
|
@ -18,7 +18,7 @@ use std::convert::Infallible;
|
|||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/users", get(handler));
|
||||
/// let app = Router::new().route("/users", get(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
|
@ -92,21 +92,21 @@ where
|
|||
/// ```
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// routing::nest,
|
||||
/// Router,
|
||||
/// extract::OriginalUri,
|
||||
/// http::Uri
|
||||
/// };
|
||||
///
|
||||
/// let api_routes = route(
|
||||
/// "/users",
|
||||
/// get(|uri: Uri, OriginalUri(original_uri): OriginalUri| async {
|
||||
/// // `uri` is `/users`
|
||||
/// // `original_uri` is `/api/users`
|
||||
/// }),
|
||||
/// );
|
||||
/// let api_routes = Router::new()
|
||||
/// .route(
|
||||
/// "/users",
|
||||
/// get(|uri: Uri, OriginalUri(original_uri): OriginalUri| async {
|
||||
/// // `uri` is `/users`
|
||||
/// // `original_uri` is `/api/users`
|
||||
/// }),
|
||||
/// );
|
||||
///
|
||||
/// let app = nest("/api", api_routes);
|
||||
/// let app = Router::new().nest("/api", api_routes);
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -174,7 +174,7 @@ where
|
|||
/// use axum::{
|
||||
/// extract::BodyStream,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use futures::StreamExt;
|
||||
///
|
||||
|
@ -184,7 +184,7 @@ where
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/users", get(handler));
|
||||
/// let app = Router::new().route("/users", get(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -227,7 +227,7 @@ where
|
|||
/// use axum::{
|
||||
/// extract::Body,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use futures::StreamExt;
|
||||
///
|
||||
|
@ -235,7 +235,7 @@ where
|
|||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/users", get(handler));
|
||||
/// let app = Router::new().route("/users", get(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -289,14 +289,14 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{body::Body, handler::post, route, tests::*};
|
||||
use crate::{body::Body, handler::post, tests::*, Router};
|
||||
use http::StatusCode;
|
||||
|
||||
#[tokio::test]
|
||||
async fn multiple_request_extractors() {
|
||||
async fn handler(_: Request<Body>, _: Request<Body>) {}
|
||||
|
||||
let app = route("/", post(handler));
|
||||
let app = Router::new().route("/", post(handler));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use std::{convert::Infallible, ops::Deref};
|
|||
/// use axum::{
|
||||
/// extract::TypedHeader,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use headers::UserAgent;
|
||||
///
|
||||
|
@ -24,7 +24,7 @@ use std::{convert::Infallible, ops::Deref};
|
|||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/users/:user_id/team/:team_id", get(users_teams_show));
|
||||
/// let app = Router::new().route("/users/:user_id/team/:team_id", get(users_teams_show));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -125,7 +125,7 @@ impl std::error::Error for TypedHeaderRejection {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{handler::get, response::IntoResponse, route, tests::*};
|
||||
use crate::{handler::get, response::IntoResponse, tests::*, Router};
|
||||
|
||||
#[tokio::test]
|
||||
async fn typed_header() {
|
||||
|
@ -135,7 +135,7 @@ mod tests {
|
|||
user_agent.to_string()
|
||||
}
|
||||
|
||||
let app = route("/", get(handle));
|
||||
let app = Router::new().route("/", get(handle));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
//! extract::ws::{WebSocketUpgrade, WebSocket},
|
||||
//! handler::get,
|
||||
//! response::IntoResponse,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//!
|
||||
//! let app = route("/ws", get(handler));
|
||||
//! let app = Router::new().route("/ws", get(handler));
|
||||
//!
|
||||
//! async fn handler(ws: WebSocketUpgrade) -> impl IntoResponse {
|
||||
//! ws.on_upgrade(handle_socket)
|
||||
|
@ -113,10 +113,10 @@ impl WebSocketUpgrade {
|
|||
/// extract::ws::{WebSocketUpgrade, WebSocket},
|
||||
/// handler::get,
|
||||
/// response::IntoResponse,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
///
|
||||
/// let app = route("/ws", get(handler));
|
||||
/// let app = Router::new().route("/ws", get(handler));
|
||||
///
|
||||
/// async fn handler(ws: WebSocketUpgrade) -> impl IntoResponse {
|
||||
/// ws.protocols(["graphql-ws", "graphql-transport-ws"])
|
||||
|
|
|
@ -33,13 +33,13 @@ pub use self::into_service::IntoService;
|
|||
/// ```rust
|
||||
/// use axum::{
|
||||
/// handler::any,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
///
|
||||
/// async fn handler() {}
|
||||
///
|
||||
/// // All requests to `/` will go to `handler` regardless of the HTTP method.
|
||||
/// let app = route("/", any(handler));
|
||||
/// let app = Router::new().route("/", any(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -78,13 +78,13 @@ where
|
|||
/// ```rust
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
///
|
||||
/// async fn handler() {}
|
||||
///
|
||||
/// // Requests to `GET /` will go to `handler`.
|
||||
/// let app = route("/", get(handler));
|
||||
/// let app = Router::new().route("/", get(handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -167,14 +167,14 @@ where
|
|||
/// ```rust
|
||||
/// use axum::{
|
||||
/// handler::on,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// routing::MethodFilter,
|
||||
/// };
|
||||
///
|
||||
/// async fn handler() {}
|
||||
///
|
||||
/// // Requests to `POST /` will go to `handler`.
|
||||
/// let app = route("/", on(MethodFilter::POST, handler));
|
||||
/// let app = Router::new().route("/", on(MethodFilter::POST, handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -234,14 +234,14 @@ pub trait Handler<B, T>: Clone + Send + Sized + 'static {
|
|||
/// ```rust
|
||||
/// use axum::{
|
||||
/// handler::{get, Handler},
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use tower::limit::{ConcurrencyLimitLayer, ConcurrencyLimit};
|
||||
///
|
||||
/// async fn handler() { /* ... */ }
|
||||
///
|
||||
/// let layered_handler = handler.layer(ConcurrencyLimitLayer::new(64));
|
||||
/// let app = route("/", get(layered_handler));
|
||||
/// let app = Router::new().route("/", get(layered_handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -511,7 +511,7 @@ impl<H, B, T, F> OnMethod<H, B, T, F> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use axum::{handler::post, route};
|
||||
/// use axum::{handler::post, Router};
|
||||
///
|
||||
/// async fn handler() {}
|
||||
///
|
||||
|
@ -519,7 +519,7 @@ impl<H, B, T, F> OnMethod<H, B, T, F> {
|
|||
///
|
||||
/// // Requests to `GET /` will go to `handler` and `POST /` will go to
|
||||
/// // `other_handler`.
|
||||
/// let app = route("/", post(handler).get(other_handler));
|
||||
/// let app = Router::new().route("/", post(handler).get(other_handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -603,7 +603,7 @@ impl<H, B, T, F> OnMethod<H, B, T, F> {
|
|||
/// ```rust
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// routing::MethodFilter
|
||||
/// };
|
||||
///
|
||||
|
@ -613,7 +613,7 @@ impl<H, B, T, F> OnMethod<H, B, T, F> {
|
|||
///
|
||||
/// // Requests to `GET /` will go to `handler` and `DELETE /` will go to
|
||||
/// // `other_handler`
|
||||
/// let app = route("/", get(handler).on(MethodFilter::DELETE, other_handler));
|
||||
/// let app = Router::new().route("/", get(handler).on(MethodFilter::DELETE, other_handler));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
|
@ -30,7 +30,7 @@ use tower::BoxError;
|
|||
/// use axum::{
|
||||
/// extract,
|
||||
/// handler::post,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use serde::Deserialize;
|
||||
///
|
||||
|
@ -44,7 +44,7 @@ use tower::BoxError;
|
|||
/// // payload is a `CreateUser`
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/users", post(create_user));
|
||||
/// let app = Router::new().route("/users", post(create_user));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -59,7 +59,7 @@ use tower::BoxError;
|
|||
/// use axum::{
|
||||
/// extract::Path,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// Json,
|
||||
/// };
|
||||
/// use serde::Serialize;
|
||||
|
@ -81,7 +81,7 @@ use tower::BoxError;
|
|||
/// # unimplemented!()
|
||||
/// }
|
||||
///
|
||||
/// let app = route("/users/:id", get(get_user));
|
||||
/// let app = Router::new().route("/users/:id", get(get_user));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
248
src/lib.rs
248
src/lib.rs
|
@ -48,13 +48,13 @@
|
|||
//! ```rust,no_run
|
||||
//! use axum::{
|
||||
//! handler::get,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//!
|
||||
//! #[tokio::main]
|
||||
//! async fn main() {
|
||||
//! // build our application with a single route
|
||||
//! let app = route("/", get(|| async { "Hello, World!" }));
|
||||
//! let app = Router::new().route("/", get(|| async { "Hello, World!" }));
|
||||
//!
|
||||
//! // run it with hyper on localhost:3000
|
||||
//! axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
|
@ -105,10 +105,11 @@
|
|||
//! ```rust,no_run
|
||||
//! use axum::{
|
||||
//! handler::get,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//!
|
||||
//! let app = route("/", get(get_slash).post(post_slash))
|
||||
//! let app = Router::new()
|
||||
//! .route("/", get(get_slash).post(post_slash))
|
||||
//! .route("/foo", get(get_foo));
|
||||
//!
|
||||
//! async fn get_slash() {
|
||||
|
@ -142,7 +143,7 @@
|
|||
//! body::{Body, BoxBody},
|
||||
//! handler::get,
|
||||
//! http::Request,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use tower::{Service, ServiceExt};
|
||||
//! use http::{Method, Response, StatusCode};
|
||||
|
@ -152,7 +153,8 @@
|
|||
//! # async fn main() {
|
||||
//! // `/foo` also matches `/:key` so adding the routes in this order means `/foo`
|
||||
//! // will be inaccessible.
|
||||
//! let mut app = route("/foo", get(|| async { "/foo called" }))
|
||||
//! let mut app = Router::new()
|
||||
//! .route("/foo", get(|| async { "/foo called" }))
|
||||
//! .route("/:key", get(|| async { "/:key called" }));
|
||||
//!
|
||||
//! // Even though we use `/foo` as the request URI, `/:key` takes precedence
|
||||
|
@ -163,7 +165,8 @@
|
|||
//!
|
||||
//! // We have to add `/foo` after `/:key` since routes are matched bottom to
|
||||
//! // top.
|
||||
//! let mut new_app = route("/:key", get(|| async { "/:key called" }))
|
||||
//! let mut new_app = Router::new()
|
||||
//! .route("/:key", get(|| async { "/:key called" }))
|
||||
//! .route("/foo", get(|| async { "/foo called" }));
|
||||
//!
|
||||
//! // Now it works
|
||||
|
@ -207,15 +210,15 @@
|
|||
//!
|
||||
//! ```rust,no_run
|
||||
//! use axum::{
|
||||
//! route,
|
||||
//! Router,
|
||||
//! handler::{get, post},
|
||||
//! };
|
||||
//!
|
||||
//! // `GET /` and `POST /` are both accepted
|
||||
//! let app = route("/", get(handler).post(handler));
|
||||
//! let app = Router::new().route("/", get(handler).post(handler));
|
||||
//!
|
||||
//! // This will _not_ work. Only `POST /` will be accessible.
|
||||
//! let wont_work = route("/", get(handler)).route("/", post(handler));
|
||||
//! let wont_work = Router::new().route("/", get(handler)).route("/", post(handler));
|
||||
//!
|
||||
//! async fn handler() {}
|
||||
//! # async {
|
||||
|
@ -232,7 +235,7 @@
|
|||
//! use axum::{
|
||||
//! body::Body,
|
||||
//! http::Request,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! service
|
||||
//! };
|
||||
//! use tower_http::services::ServeFile;
|
||||
|
@ -240,31 +243,34 @@
|
|||
//! use std::convert::Infallible;
|
||||
//! use tower::service_fn;
|
||||
//!
|
||||
//! let app = route(
|
||||
//! // Any request to `/` goes to a service
|
||||
//! "/",
|
||||
//! // Services who's response body is not `axum::body::BoxBody`
|
||||
//! // can be wrapped in `axum::service::any` (or one of the other routing filters)
|
||||
//! // to have the response body mapped
|
||||
//! service::any(service_fn(|_: Request<Body>| async {
|
||||
//! let res = Response::new(Body::from("Hi from `GET /`"));
|
||||
//! Ok(res)
|
||||
//! }))
|
||||
//! ).route(
|
||||
//! "/foo",
|
||||
//! // This service's response body is `axum::body::BoxBody` so
|
||||
//! // it can be routed to directly.
|
||||
//! service_fn(|req: Request<Body>| async move {
|
||||
//! let body = Body::from(format!("Hi from `{} /foo`", req.method()));
|
||||
//! let body = axum::body::box_body(body);
|
||||
//! let res = Response::new(body);
|
||||
//! Ok(res)
|
||||
//! })
|
||||
//! ).route(
|
||||
//! // GET `/static/Cargo.toml` goes to a service from tower-http
|
||||
//! "/static/Cargo.toml",
|
||||
//! service::get(ServeFile::new("Cargo.toml"))
|
||||
//! );
|
||||
//! let app = Router::new()
|
||||
//! .route(
|
||||
//! // Any request to `/` goes to a service
|
||||
//! "/",
|
||||
//! // Services who's response body is not `axum::body::BoxBody`
|
||||
//! // can be wrapped in `axum::service::any` (or one of the other routing filters)
|
||||
//! // to have the response body mapped
|
||||
//! service::any(service_fn(|_: Request<Body>| async {
|
||||
//! let res = Response::new(Body::from("Hi from `GET /`"));
|
||||
//! Ok(res)
|
||||
//! }))
|
||||
//! )
|
||||
//! .route(
|
||||
//! "/foo",
|
||||
//! // This service's response body is `axum::body::BoxBody` so
|
||||
//! // it can be routed to directly.
|
||||
//! service_fn(|req: Request<Body>| async move {
|
||||
//! let body = Body::from(format!("Hi from `{} /foo`", req.method()));
|
||||
//! let body = axum::body::box_body(body);
|
||||
//! let res = Response::new(body);
|
||||
//! Ok(res)
|
||||
//! })
|
||||
//! )
|
||||
//! .route(
|
||||
//! // GET `/static/Cargo.toml` goes to a service from tower-http
|
||||
//! "/static/Cargo.toml",
|
||||
//! service::get(ServeFile::new("Cargo.toml"))
|
||||
//! );
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
//! # };
|
||||
|
@ -275,24 +281,27 @@
|
|||
//!
|
||||
//! ## Nesting Routes
|
||||
//!
|
||||
//! Routes can be nested by calling [`nest`](routing::nest):
|
||||
//! Routes can be nested by calling [`Router::nest`](routing::Router::nest):
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use axum::{
|
||||
//! body::{Body, BoxBody},
|
||||
//! http::Request,
|
||||
//! handler::get,
|
||||
//! route,
|
||||
//! routing::{BoxRoute, Router}
|
||||
//! Router,
|
||||
//! routing::BoxRoute
|
||||
//! };
|
||||
//! use tower_http::services::ServeFile;
|
||||
//! use http::Response;
|
||||
//!
|
||||
//! fn api_routes() -> Router<BoxRoute> {
|
||||
//! route("/users", get(|_: Request<Body>| async { /* ... */ })).boxed()
|
||||
//! Router::new()
|
||||
//! .route("/users", get(|_: Request<Body>| async { /* ... */ }))
|
||||
//! .boxed()
|
||||
//! }
|
||||
//!
|
||||
//! let app = route("/", get(|_: Request<Body>| async { /* ... */ }))
|
||||
//! let app = Router::new()
|
||||
//! .route("/", get(|_: Request<Body>| async { /* ... */ }))
|
||||
//! .nest("/api", api_routes());
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
|
@ -316,11 +325,11 @@
|
|||
//! use axum::{
|
||||
//! extract,
|
||||
//! handler::post,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use serde::Deserialize;
|
||||
//!
|
||||
//! let app = route("/users", post(create_user));
|
||||
//! let app = Router::new().route("/users", post(create_user));
|
||||
//!
|
||||
//! #[derive(Deserialize)]
|
||||
//! struct CreateUser {
|
||||
|
@ -346,11 +355,11 @@
|
|||
//! use axum::{
|
||||
//! extract,
|
||||
//! handler::post,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use uuid::Uuid;
|
||||
//!
|
||||
//! let app = route("/users/:id", post(create_user));
|
||||
//! let app = Router::new().route("/users/:id", post(create_user));
|
||||
//!
|
||||
//! async fn create_user(extract::Path(user_id): extract::Path<Uuid>) {
|
||||
//! // ...
|
||||
|
@ -366,12 +375,12 @@
|
|||
//! use axum::{
|
||||
//! extract,
|
||||
//! handler::get,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use uuid::Uuid;
|
||||
//! use serde::Deserialize;
|
||||
//!
|
||||
//! let app = route("/users/:id/things", get(get_user_things));
|
||||
//! let app = Router::new().route("/users/:id/things", get(get_user_things));
|
||||
//!
|
||||
//! #[derive(Deserialize)]
|
||||
//! struct Pagination {
|
||||
|
@ -405,10 +414,10 @@
|
|||
//! body::Body,
|
||||
//! handler::post,
|
||||
//! http::Request,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//!
|
||||
//! let app = route("/users/:id", post(handler));
|
||||
//! let app = Router::new().route("/users/:id", post(handler));
|
||||
//!
|
||||
//! async fn handler(req: Request<Body>) {
|
||||
//! // ...
|
||||
|
@ -437,7 +446,7 @@
|
|||
//! handler::{get, Handler},
|
||||
//! http::Request,
|
||||
//! response::{Html, Json},
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use http::{StatusCode, Response, Uri};
|
||||
//! use serde_json::{Value, json};
|
||||
|
@ -493,7 +502,8 @@
|
|||
//! Response::builder().body(Body::empty()).unwrap()
|
||||
//! }
|
||||
//!
|
||||
//! let app = route("/plain_text", get(plain_text))
|
||||
//! let app = Router::new()
|
||||
//! .route("/plain_text", get(plain_text))
|
||||
//! .route("/plain_text_string", get(plain_text_string))
|
||||
//! .route("/bytes", get(bytes))
|
||||
//! .route("/empty", get(empty))
|
||||
|
@ -520,14 +530,15 @@
|
|||
//! ```rust,no_run
|
||||
//! use axum::{
|
||||
//! handler::{get, Handler},
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use tower::limit::ConcurrencyLimitLayer;
|
||||
//!
|
||||
//! let app = route(
|
||||
//! "/",
|
||||
//! get(handler.layer(ConcurrencyLimitLayer::new(100))),
|
||||
//! );
|
||||
//! let app = Router::new()
|
||||
//! .route(
|
||||
//! "/",
|
||||
//! get(handler.layer(ConcurrencyLimitLayer::new(100))),
|
||||
//! );
|
||||
//!
|
||||
//! async fn handler() {}
|
||||
//! # async {
|
||||
|
@ -542,11 +553,12 @@
|
|||
//! ```rust,no_run
|
||||
//! use axum::{
|
||||
//! handler::{get, post},
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use tower::limit::ConcurrencyLimitLayer;
|
||||
//!
|
||||
//! let app = route("/", get(get_slash))
|
||||
//! let app = Router::new()
|
||||
//! .route("/", get(get_slash))
|
||||
//! .route("/foo", post(post_foo))
|
||||
//! .layer(ConcurrencyLimitLayer::new(100));
|
||||
//!
|
||||
|
@ -575,7 +587,7 @@
|
|||
//! ```rust,no_run
|
||||
//! use axum::{
|
||||
//! handler::{get, Handler},
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use tower::{
|
||||
//! BoxError, timeout::{TimeoutLayer, error::Elapsed},
|
||||
|
@ -583,30 +595,31 @@
|
|||
//! use std::{borrow::Cow, time::Duration, convert::Infallible};
|
||||
//! use http::StatusCode;
|
||||
//!
|
||||
//! let app = route(
|
||||
//! "/",
|
||||
//! get(handle
|
||||
//! .layer(TimeoutLayer::new(Duration::from_secs(30)))
|
||||
//! // `Timeout` uses `BoxError` as the error type
|
||||
//! .handle_error(|error: BoxError| {
|
||||
//! // Check if the actual error type is `Elapsed` which
|
||||
//! // `Timeout` returns
|
||||
//! if error.is::<Elapsed>() {
|
||||
//! return Ok::<_, Infallible>((
|
||||
//! StatusCode::REQUEST_TIMEOUT,
|
||||
//! "Request took too long".into(),
|
||||
//! ));
|
||||
//! }
|
||||
//! let app = Router::new()
|
||||
//! .route(
|
||||
//! "/",
|
||||
//! get(handle
|
||||
//! .layer(TimeoutLayer::new(Duration::from_secs(30)))
|
||||
//! // `Timeout` uses `BoxError` as the error type
|
||||
//! .handle_error(|error: BoxError| {
|
||||
//! // Check if the actual error type is `Elapsed` which
|
||||
//! // `Timeout` returns
|
||||
//! if error.is::<Elapsed>() {
|
||||
//! return Ok::<_, Infallible>((
|
||||
//! StatusCode::REQUEST_TIMEOUT,
|
||||
//! "Request took too long".into(),
|
||||
//! ));
|
||||
//! }
|
||||
//!
|
||||
//! // If we encounter some error we don't handle return a generic
|
||||
//! // error
|
||||
//! return Ok::<_, Infallible>((
|
||||
//! StatusCode::INTERNAL_SERVER_ERROR,
|
||||
//! // `Cow` lets us return either `&str` or `String`
|
||||
//! Cow::from(format!("Unhandled internal error: {}", error)),
|
||||
//! ));
|
||||
//! })),
|
||||
//! );
|
||||
//! // If we encounter some error we don't handle return a generic
|
||||
//! // error
|
||||
//! return Ok::<_, Infallible>((
|
||||
//! StatusCode::INTERNAL_SERVER_ERROR,
|
||||
//! // `Cow` lets us return either `&str` or `String`
|
||||
//! Cow::from(format!("Unhandled internal error: {}", error)),
|
||||
//! ));
|
||||
//! })),
|
||||
//! );
|
||||
//!
|
||||
//! async fn handle() {}
|
||||
//! # async {
|
||||
|
@ -629,7 +642,7 @@
|
|||
//! body::Body,
|
||||
//! handler::get,
|
||||
//! http::Request,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use tower::ServiceBuilder;
|
||||
//! use tower_http::compression::CompressionLayer;
|
||||
|
@ -646,7 +659,8 @@
|
|||
//! .layer(CompressionLayer::new())
|
||||
//! .into_inner();
|
||||
//!
|
||||
//! let app = route("/", get(|_: Request<Body>| async { /* ... */ }))
|
||||
//! let app = Router::new()
|
||||
//! .route("/", get(|_: Request<Body>| async { /* ... */ }))
|
||||
//! .layer(middleware_stack);
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
|
@ -665,7 +679,7 @@
|
|||
//! AddExtensionLayer,
|
||||
//! extract,
|
||||
//! handler::get,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use std::sync::Arc;
|
||||
//!
|
||||
|
@ -675,7 +689,9 @@
|
|||
//!
|
||||
//! let shared_state = Arc::new(State { /* ... */ });
|
||||
//!
|
||||
//! let app = route("/", get(handler)).layer(AddExtensionLayer::new(shared_state));
|
||||
//! let app = Router::new()
|
||||
//! .route("/", get(handler))
|
||||
//! .layer(AddExtensionLayer::new(shared_state));
|
||||
//!
|
||||
//! async fn handler(
|
||||
//! state: extract::Extension<Arc<State>>,
|
||||
|
@ -738,6 +754,8 @@
|
|||
//! [`Router::or`]: crate::routing::Router::or
|
||||
//! [`axum::Server`]: hyper::server::Server
|
||||
//! [`OriginalUri`]: crate::extract::OriginalUri
|
||||
//! [`Service`]: tower::Service
|
||||
//! [`Service::poll_ready`]: tower::Service::poll_ready
|
||||
|
||||
#![warn(
|
||||
clippy::all,
|
||||
|
@ -779,10 +797,6 @@
|
|||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(test, allow(clippy::float_cmp))]
|
||||
|
||||
use http::Request;
|
||||
use routing::{EmptyRouter, Route};
|
||||
use tower::Service;
|
||||
|
||||
#[macro_use]
|
||||
pub(crate) mod macros;
|
||||
|
||||
|
@ -810,56 +824,4 @@ pub use hyper::Server;
|
|||
#[doc(no_inline)]
|
||||
pub use tower_http::add_extension::{AddExtension, AddExtensionLayer};
|
||||
|
||||
pub use self::{error::Error, json::Json};
|
||||
|
||||
/// Create a route.
|
||||
///
|
||||
/// `description` is a string of path segments separated by `/`. Each segment
|
||||
/// can be either concrete or a capture:
|
||||
///
|
||||
/// - `/foo/bar/baz` will only match requests where the path is `/foo/bar/bar`.
|
||||
/// - `/:foo` will match any route with exactly one segment _and_ it will
|
||||
/// capture the first segment and store it at the key `foo`.
|
||||
///
|
||||
/// `service` is the [`Service`] that should receive the request if the path
|
||||
/// matches `description`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use axum::{
|
||||
/// body::Body,
|
||||
/// http::Request,
|
||||
/// route
|
||||
/// };
|
||||
///
|
||||
/// # use std::convert::Infallible;
|
||||
/// # use http::Response;
|
||||
/// # let service = tower::service_fn(|_: Request<Body>| async {
|
||||
/// # Ok::<Response<Body>, Infallible>(Response::new(Body::empty()))
|
||||
/// # });
|
||||
///
|
||||
/// route("/", service);
|
||||
/// route("/users", service);
|
||||
/// route("/users/:id", service);
|
||||
/// route("/api/:version/users/:id/action", service);
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `description` doesn't start with `/`.
|
||||
pub fn route<S, B>(
|
||||
description: &str,
|
||||
service: S,
|
||||
) -> routing::Router<Route<S, EmptyRouter<S::Error>>>
|
||||
where
|
||||
S: Service<Request<B>> + Clone,
|
||||
{
|
||||
routing::Router::new().route(description, service)
|
||||
}
|
||||
|
||||
mod sealed {
|
||||
#![allow(unreachable_pub, missing_docs)]
|
||||
|
||||
pub trait Sealed {}
|
||||
}
|
||||
pub use self::{error::Error, json::Json, routing::Router};
|
||||
|
|
|
@ -13,7 +13,7 @@ use tower::{util::Either, BoxError};
|
|||
///
|
||||
/// ```rust
|
||||
/// use axum::{
|
||||
/// route,
|
||||
/// Router,
|
||||
/// response::{IntoResponse, Headers},
|
||||
/// handler::get,
|
||||
/// };
|
||||
|
@ -36,7 +36,8 @@ use tower::{util::Either, BoxError};
|
|||
///
|
||||
/// // Or `[(&str, &str)]` if you're on Rust 1.53+
|
||||
///
|
||||
/// let app = route("/just-headers", get(just_headers))
|
||||
/// let app = Router::new()
|
||||
/// .route("/just-headers", get(just_headers))
|
||||
/// .route("/from-strings", get(from_strings));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
|
|
|
@ -44,7 +44,7 @@ pub use self::{
|
|||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// response::IntoResponse,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use http_body::Body;
|
||||
/// use http::{Response, HeaderMap};
|
||||
|
@ -94,7 +94,7 @@ pub use self::{
|
|||
/// // covered by a blanket implementation in axum.
|
||||
///
|
||||
/// // `MyBody` can now be returned from handlers.
|
||||
/// let app = route("/", get(|| async { MyBody }));
|
||||
/// let app = Router::new().route("/", get(|| async { MyBody }));
|
||||
/// # async {
|
||||
/// # hyper::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
|
@ -12,10 +12,11 @@ use std::convert::TryFrom;
|
|||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// response::Redirect,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
///
|
||||
/// let app = route("/old", get(|| async { Redirect::permanent("/new".parse().unwrap()) }))
|
||||
/// let app = Router::new()
|
||||
/// .route("/old", get(|| async { Redirect::permanent("/new".parse().unwrap()) }))
|
||||
/// .route("/new", get(|| async { "Hello!" }));
|
||||
/// # async {
|
||||
/// # hyper::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
//! ```
|
||||
//! use axum::{
|
||||
//! handler::get,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use axum::response::sse::{sse, Event, KeepAlive, Sse};
|
||||
//! use std::{time::Duration, convert::Infallible};
|
||||
//! use tokio_stream::StreamExt as _ ;
|
||||
//! use futures::stream::{self, Stream};
|
||||
//!
|
||||
//! let app = route("/sse", get(sse_handler));
|
||||
//! let app = Router::new().route("/sse", get(sse_handler));
|
||||
//!
|
||||
//! async fn sse_handler() -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
|
||||
//! // A `Stream` that repeats an event every second
|
||||
|
|
|
@ -81,28 +81,44 @@ where
|
|||
impl<S> Router<S> {
|
||||
/// Add another route to the router.
|
||||
///
|
||||
/// `description` is a string of path segments separated by `/`. Each segment
|
||||
/// can be either concrete or a capture:
|
||||
///
|
||||
/// - `/foo/bar/baz` will only match requests where the path is `/foo/bar/bar`.
|
||||
/// - `/:foo` will match any route with exactly one segment _and_ it will
|
||||
/// capture the first segment and store it at the key `foo`.
|
||||
///
|
||||
/// `service` is the [`Service`] that should receive the request if the path
|
||||
/// matches `description`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// };
|
||||
/// use axum::{handler::{get, delete}, Router};
|
||||
///
|
||||
/// async fn first_handler() { /* ... */ }
|
||||
/// let app = Router::new()
|
||||
/// .route("/", get(root))
|
||||
/// .route("/users", get(list_users).post(create_user))
|
||||
/// .route("/users/:id", get(show_user))
|
||||
/// .route("/api/:version/users/:id/action", delete(do_thing));
|
||||
///
|
||||
/// async fn second_handler() { /* ... */ }
|
||||
/// async fn root() { /* ... */ }
|
||||
///
|
||||
/// async fn third_handler() { /* ... */ }
|
||||
/// async fn list_users() { /* ... */ }
|
||||
///
|
||||
/// // `GET /` goes to `first_handler`, `POST /` goes to `second_handler`,
|
||||
/// // and `GET /foo` goes to third_handler.
|
||||
/// let app = route("/", get(first_handler).post(second_handler))
|
||||
/// .route("/foo", get(third_handler));
|
||||
/// async fn create_user() { /* ... */ }
|
||||
///
|
||||
/// async fn show_user() { /* ... */ }
|
||||
///
|
||||
/// async fn do_thing() { /* ... */ }
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `description` doesn't start with `/`.
|
||||
pub fn route<T, B>(self, description: &str, svc: T) -> Router<Route<T, S>>
|
||||
where
|
||||
T: Service<Request<B>> + Clone,
|
||||
|
@ -114,9 +130,83 @@ impl<S> Router<S> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Nest another service inside this router at the given path.
|
||||
/// Nest a group of routes (or a [`Service`]) at some path.
|
||||
///
|
||||
/// See [`nest`] for more details.
|
||||
/// This allows you to break your application into smaller pieces and compose
|
||||
/// them together.
|
||||
///
|
||||
/// ```
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use http::Uri;
|
||||
///
|
||||
/// async fn users_get(uri: Uri) {
|
||||
/// // `users_get` will still see the whole URI.
|
||||
/// assert_eq!(uri.path(), "/api/users");
|
||||
/// }
|
||||
///
|
||||
/// async fn users_post() {}
|
||||
///
|
||||
/// async fn careers() {}
|
||||
///
|
||||
/// let users_api = Router::new().route("/users", get(users_get).post(users_post));
|
||||
///
|
||||
/// let app = Router::new().nest("/api", users_api).route("/careers", get(careers));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// Take care when using `nest` together with dynamic routes as nesting also
|
||||
/// captures from the outer routes:
|
||||
///
|
||||
/// ```
|
||||
/// use axum::{
|
||||
/// extract::Path,
|
||||
/// handler::get,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use std::collections::HashMap;
|
||||
///
|
||||
/// async fn users_get(Path(params): Path<HashMap<String, String>>) {
|
||||
/// // Both `version` and `id` were captured even though `users_api` only
|
||||
/// // explicitly captures `id`.
|
||||
/// let version = params.get("version");
|
||||
/// let id = params.get("id");
|
||||
/// }
|
||||
///
|
||||
/// let users_api = Router::new().route("/users/:id", get(users_get));
|
||||
///
|
||||
/// let app = Router::new().nest("/:version/api", users_api);
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// `nest` also accepts any [`Service`]. This can for example be used with
|
||||
/// [`tower_http::services::ServeDir`] to serve static files from a directory:
|
||||
///
|
||||
/// ```
|
||||
/// use axum::{
|
||||
/// Router,
|
||||
/// service::get,
|
||||
/// };
|
||||
/// use tower_http::services::ServeDir;
|
||||
///
|
||||
/// // Serves files inside the `public` directory at `GET /public/*`
|
||||
/// let serve_dir_service = ServeDir::new("public");
|
||||
///
|
||||
/// let app = Router::new().nest("/public", get(serve_dir_service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// If necessary you can use [`Router::boxed`] to box a group of routes
|
||||
/// making the type easier to name. This is sometimes useful when working with
|
||||
/// `nest`.
|
||||
pub fn nest<T, B>(self, description: &str, svc: T) -> Router<Nested<T, S>>
|
||||
where
|
||||
T: Service<Request<B>> + Clone,
|
||||
|
@ -137,8 +227,8 @@ impl<S> Router<S> {
|
|||
/// use axum::{
|
||||
/// body::Body,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// routing::{Router, BoxRoute}
|
||||
/// Router,
|
||||
/// routing::BoxRoute
|
||||
/// };
|
||||
///
|
||||
/// async fn first_handler() { /* ... */ }
|
||||
|
@ -148,7 +238,8 @@ impl<S> Router<S> {
|
|||
/// async fn third_handler() { /* ... */ }
|
||||
///
|
||||
/// fn app() -> Router<BoxRoute> {
|
||||
/// route("/", get(first_handler).post(second_handler))
|
||||
/// Router::new()
|
||||
/// .route("/", get(first_handler).post(second_handler))
|
||||
/// .route("/foo", get(third_handler))
|
||||
/// .boxed()
|
||||
/// }
|
||||
|
@ -195,7 +286,7 @@ impl<S> Router<S> {
|
|||
/// ```rust
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use tower::limit::{ConcurrencyLimitLayer, ConcurrencyLimit};
|
||||
///
|
||||
|
@ -207,7 +298,7 @@ impl<S> Router<S> {
|
|||
///
|
||||
/// // All requests to `handler` and `other_handler` will be sent through
|
||||
/// // `ConcurrencyLimit`
|
||||
/// let app = route("/", get(first_handler))
|
||||
/// let app = Router::new().route("/", get(first_handler))
|
||||
/// .route("/foo", get(second_handler))
|
||||
/// .layer(ConcurrencyLimitLayer::new(64))
|
||||
/// // Request to `GET /bar` will go directly to `third_handler` and
|
||||
|
@ -224,7 +315,7 @@ impl<S> Router<S> {
|
|||
/// ```rust
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use tower_http::trace::TraceLayer;
|
||||
///
|
||||
|
@ -234,7 +325,8 @@ impl<S> Router<S> {
|
|||
///
|
||||
/// async fn third_handler() { /* ... */ }
|
||||
///
|
||||
/// let app = route("/", get(first_handler))
|
||||
/// let app = Router::new()
|
||||
/// .route("/", get(first_handler))
|
||||
/// .route("/foo", get(second_handler))
|
||||
/// .route("/bar", get(third_handler))
|
||||
/// .layer(TraceLayer::new_for_http());
|
||||
|
@ -258,10 +350,10 @@ impl<S> Router<S> {
|
|||
/// ```
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
///
|
||||
/// let app = route("/", get(|| async { "Hi!" }));
|
||||
/// let app = Router::new().route("/", get(|| async { "Hi!" }));
|
||||
///
|
||||
/// # async {
|
||||
/// axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
|
@ -291,11 +383,11 @@ impl<S> Router<S> {
|
|||
/// use axum::{
|
||||
/// extract::ConnectInfo,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use std::net::SocketAddr;
|
||||
///
|
||||
/// let app = route("/", get(handler));
|
||||
/// let app = Router::new().route("/", get(handler));
|
||||
///
|
||||
/// async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
|
||||
/// format!("Hello {}", addr)
|
||||
|
@ -317,11 +409,11 @@ impl<S> Router<S> {
|
|||
/// use axum::{
|
||||
/// extract::connect_info::{ConnectInfo, Connected},
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use hyper::server::conn::AddrStream;
|
||||
///
|
||||
/// let app = route("/", get(handler));
|
||||
/// let app = Router::new().route("/", get(handler));
|
||||
///
|
||||
/// async fn handler(
|
||||
/// ConnectInfo(my_connect_info): ConnectInfo<MyConnectInfo>,
|
||||
|
@ -379,7 +471,7 @@ impl<S> Router<S> {
|
|||
/// ```
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// #
|
||||
/// # async fn users_list() {}
|
||||
|
@ -387,10 +479,10 @@ impl<S> Router<S> {
|
|||
/// # async fn teams_list() {}
|
||||
///
|
||||
/// // define some routes separately
|
||||
/// let user_routes = route("/users", get(users_list))
|
||||
/// let user_routes = Router::new().route("/users", get(users_list))
|
||||
/// .route("/users/:id", get(users_show));
|
||||
///
|
||||
/// let team_routes = route("/teams", get(teams_list));
|
||||
/// let team_routes = Router::new().route("/teams", get(teams_list));
|
||||
///
|
||||
/// // combine them into one
|
||||
/// let app = user_routes.or(team_routes);
|
||||
|
@ -416,13 +508,13 @@ impl<S> Router<S> {
|
|||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// http::StatusCode,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use tower::{BoxError, timeout::TimeoutLayer};
|
||||
/// use std::{time::Duration, convert::Infallible};
|
||||
///
|
||||
/// // This router can never fail, since handlers can never fail.
|
||||
/// let app = route("/", get(|| async {}));
|
||||
/// let app = Router::new().route("/", get(|| async {}));
|
||||
///
|
||||
/// // Now the router can fail since the `tower::timeout::Timeout`
|
||||
/// // middleware will return an error if the timeout elapses.
|
||||
|
@ -455,12 +547,13 @@ impl<S> Router<S> {
|
|||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// http::StatusCode,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// };
|
||||
/// use tower::{BoxError, timeout::TimeoutLayer};
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let app = route("/", get(|| async {}))
|
||||
/// let app = Router::new()
|
||||
/// .route("/", get(|| async {}))
|
||||
/// .layer(TimeoutLayer::new(Duration::from_secs(10)))
|
||||
/// .handle_error(|error: BoxError| {
|
||||
/// if error.is::<tower::timeout::error::Elapsed>() {
|
||||
|
@ -498,8 +591,6 @@ impl<S> Router<S> {
|
|||
|
||||
/// A route that sends requests to one of two [`Service`]s depending on the
|
||||
/// path.
|
||||
///
|
||||
/// Created with [`route`](crate::route). See that function for more details.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Route<S, F> {
|
||||
pub(crate) pattern: PathPattern,
|
||||
|
@ -845,95 +936,9 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Nest a group of routes (or a [`Service`]) at some path.
|
||||
///
|
||||
/// This allows you to break your application into smaller pieces and compose
|
||||
/// them together.
|
||||
///
|
||||
/// ```
|
||||
/// use axum::{
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// routing::nest,
|
||||
/// };
|
||||
/// use http::Uri;
|
||||
///
|
||||
/// async fn users_get(uri: Uri) {
|
||||
/// // `users_get` will still see the whole URI.
|
||||
/// assert_eq!(uri.path(), "/api/users");
|
||||
/// }
|
||||
///
|
||||
/// async fn users_post() {}
|
||||
///
|
||||
/// async fn careers() {}
|
||||
///
|
||||
/// let users_api = route("/users", get(users_get).post(users_post));
|
||||
///
|
||||
/// let app = nest("/api", users_api).route("/careers", get(careers));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// Take care when using `nest` together with dynamic routes as nesting also
|
||||
/// captures from the outer routes:
|
||||
///
|
||||
/// ```
|
||||
/// use axum::{
|
||||
/// extract::Path,
|
||||
/// handler::get,
|
||||
/// route,
|
||||
/// routing::nest,
|
||||
/// };
|
||||
/// use std::collections::HashMap;
|
||||
///
|
||||
/// async fn users_get(Path(params): Path<HashMap<String, String>>) {
|
||||
/// // Both `version` and `id` were captured even though `users_api` only
|
||||
/// // explicitly captures `id`.
|
||||
/// let version = params.get("version");
|
||||
/// let id = params.get("id");
|
||||
/// }
|
||||
///
|
||||
/// let users_api = route("/users/:id", get(users_get));
|
||||
///
|
||||
/// let app = nest("/:version/api", users_api);
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// `nest` also accepts any [`Service`]. This can for example be used with
|
||||
/// [`tower_http::services::ServeDir`] to serve static files from a directory:
|
||||
///
|
||||
/// ```
|
||||
/// use axum::{
|
||||
/// routing::nest,
|
||||
/// service::get,
|
||||
/// };
|
||||
/// use tower_http::services::ServeDir;
|
||||
///
|
||||
/// // Serves files inside the `public` directory at `GET /public/*`
|
||||
/// let serve_dir_service = ServeDir::new("public");
|
||||
///
|
||||
/// let app = nest("/public", get(serve_dir_service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// If necessary you can use [`Router::boxed`] to box a group of routes
|
||||
/// making the type easier to name. This is sometimes useful when working with
|
||||
/// `nest`.
|
||||
pub fn nest<S, B>(description: &str, svc: S) -> Router<Nested<S, EmptyRouter<S::Error>>>
|
||||
where
|
||||
S: Service<Request<B>> + Clone,
|
||||
{
|
||||
Router::new().nest(description, svc)
|
||||
}
|
||||
|
||||
/// A [`Service`] that has been nested inside a router at some path.
|
||||
///
|
||||
/// Created with [`nest`] or [`Router::nest`].
|
||||
/// Created with [`Router::nest`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Nested<S, F> {
|
||||
pattern: PathPattern,
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
//! body::Body,
|
||||
//! handler::get,
|
||||
//! http::Request,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! service,
|
||||
//! };
|
||||
//!
|
||||
|
@ -23,7 +23,8 @@
|
|||
//!
|
||||
//! let redirect_service = Redirect::<Body>::permanent("/new".parse().unwrap());
|
||||
//!
|
||||
//! let app = route("/old", service::get(redirect_service))
|
||||
//! let app = Router::new()
|
||||
//! .route("/old", service::get(redirect_service))
|
||||
//! .route("/new", get(handler));
|
||||
//! # async {
|
||||
//! # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
|
@ -66,7 +67,7 @@
|
|||
//! ```rust
|
||||
//! use axum::{
|
||||
//! handler::get,
|
||||
//! route,
|
||||
//! Router,
|
||||
//! };
|
||||
//! use tower::ServiceBuilder;
|
||||
//! # let some_backpressure_sensitive_middleware =
|
||||
|
@ -74,7 +75,7 @@
|
|||
//!
|
||||
//! async fn handler() { /* ... */ }
|
||||
//!
|
||||
//! let app = route("/", get(handler));
|
||||
//! let app = Router::new().route("/", get(handler));
|
||||
//!
|
||||
//! let app = ServiceBuilder::new()
|
||||
//! .layer(some_backpressure_sensitive_middleware)
|
||||
|
@ -148,7 +149,7 @@ where
|
|||
/// ```rust
|
||||
/// use axum::{
|
||||
/// http::Request,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// service,
|
||||
/// };
|
||||
/// use http::Response;
|
||||
|
@ -160,7 +161,7 @@ where
|
|||
/// });
|
||||
///
|
||||
/// // Requests to `GET /` will go to `service`.
|
||||
/// let app = route("/", service::get(service));
|
||||
/// let app = Router::new().route("/", service::get(service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -245,7 +246,7 @@ where
|
|||
/// http::Request,
|
||||
/// handler::on,
|
||||
/// service,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// routing::MethodFilter,
|
||||
/// };
|
||||
/// use http::Response;
|
||||
|
@ -257,7 +258,7 @@ where
|
|||
/// });
|
||||
///
|
||||
/// // Requests to `POST /` will go to `service`.
|
||||
/// let app = route("/", service::on(MethodFilter::POST, service));
|
||||
/// let app = Router::new().route("/", service::on(MethodFilter::POST, service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -340,7 +341,7 @@ impl<S, F, B> OnMethod<S, F, B> {
|
|||
/// http::Request,
|
||||
/// handler::on,
|
||||
/// service,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// routing::MethodFilter,
|
||||
/// };
|
||||
/// use http::Response;
|
||||
|
@ -357,7 +358,7 @@ impl<S, F, B> OnMethod<S, F, B> {
|
|||
///
|
||||
/// // Requests to `GET /` will go to `service` and `POST /` will go to
|
||||
/// // `other_service`.
|
||||
/// let app = route("/", service::post(service).get(other_service));
|
||||
/// let app = Router::new().route("/", service::post(service).get(other_service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
@ -443,7 +444,7 @@ impl<S, F, B> OnMethod<S, F, B> {
|
|||
/// http::Request,
|
||||
/// handler::on,
|
||||
/// service,
|
||||
/// route,
|
||||
/// Router,
|
||||
/// routing::MethodFilter,
|
||||
/// };
|
||||
/// use http::Response;
|
||||
|
@ -459,7 +460,7 @@ impl<S, F, B> OnMethod<S, F, B> {
|
|||
/// });
|
||||
///
|
||||
/// // Requests to `DELETE /` will go to `service`
|
||||
/// let app = route("/", service::on(MethodFilter::DELETE, service));
|
||||
/// let app = Router::new().route("/", service::on(MethodFilter::DELETE, service));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
|
|
|
@ -7,7 +7,7 @@ mod for_handlers {
|
|||
|
||||
#[tokio::test]
|
||||
async fn get_handles_head() {
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
get(|| async {
|
||||
let mut headers = HeaderMap::new();
|
||||
|
@ -43,7 +43,7 @@ mod for_services {
|
|||
|
||||
#[tokio::test]
|
||||
async fn get_handles_head() {
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
get(service_fn(|_req: Request<Body>| async move {
|
||||
let res = Response::builder()
|
||||
|
|
|
@ -41,7 +41,7 @@ fn handle_error<E>(_: E) -> Result<StatusCode, Infallible> {
|
|||
|
||||
#[tokio::test]
|
||||
async fn handler() {
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
get(forever
|
||||
.layer(timeout())
|
||||
|
@ -62,7 +62,7 @@ async fn handler() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn handler_multiple_methods_first() {
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
get(forever
|
||||
.layer(timeout())
|
||||
|
@ -84,7 +84,7 @@ async fn handler_multiple_methods_first() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn handler_multiple_methods_middle() {
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
delete(unit)
|
||||
.get(
|
||||
|
@ -109,7 +109,7 @@ async fn handler_multiple_methods_middle() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn handler_multiple_methods_last() {
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
delete(unit).get(
|
||||
forever
|
||||
|
@ -132,21 +132,22 @@ async fn handler_multiple_methods_last() {
|
|||
|
||||
#[test]
|
||||
fn service_propagates_errors() {
|
||||
let app = route::<_, Body>("/echo", service::post(Svc));
|
||||
let app = Router::new().route::<_, Body>("/echo", service::post(Svc));
|
||||
|
||||
check_make_svc::<_, _, _, hyper::Error>(app.into_make_service());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn service_nested_propagates_errors() {
|
||||
let app = route::<_, Body>("/echo", nest("/foo", service::post(Svc)));
|
||||
let app =
|
||||
Router::new().route::<_, Body>("/echo", Router::new().nest("/foo", service::post(Svc)));
|
||||
|
||||
check_make_svc::<_, _, _, hyper::Error>(app.into_make_service());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn service_handle_on_method() {
|
||||
let app = route::<_, Body>(
|
||||
let app = Router::new().route::<_, Body>(
|
||||
"/echo",
|
||||
service::get(Svc).handle_error(handle_error::<hyper::Error>),
|
||||
);
|
||||
|
@ -156,7 +157,7 @@ fn service_handle_on_method() {
|
|||
|
||||
#[test]
|
||||
fn service_handle_on_method_multiple() {
|
||||
let app = route::<_, Body>(
|
||||
let app = Router::new().route::<_, Body>(
|
||||
"/echo",
|
||||
service::get(Svc)
|
||||
.post(Svc)
|
||||
|
@ -168,15 +169,17 @@ fn service_handle_on_method_multiple() {
|
|||
|
||||
#[test]
|
||||
fn service_handle_on_router() {
|
||||
let app =
|
||||
route::<_, Body>("/echo", service::get(Svc)).handle_error(handle_error::<hyper::Error>);
|
||||
let app = Router::new()
|
||||
.route::<_, Body>("/echo", service::get(Svc))
|
||||
.handle_error(handle_error::<hyper::Error>);
|
||||
|
||||
check_make_svc::<_, _, _, Infallible>(app.into_make_service());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn service_handle_on_router_still_impls_routing_dsl() {
|
||||
let app = route::<_, Body>("/echo", service::get(Svc))
|
||||
let app = Router::new()
|
||||
.route::<_, Body>("/echo", service::get(Svc))
|
||||
.handle_error(handle_error::<hyper::Error>)
|
||||
.route("/", get(unit));
|
||||
|
||||
|
@ -185,7 +188,8 @@ fn service_handle_on_router_still_impls_routing_dsl() {
|
|||
|
||||
#[test]
|
||||
fn layered() {
|
||||
let app = route::<_, Body>("/echo", get(unit))
|
||||
let app = Router::new()
|
||||
.route::<_, Body>("/echo", get(unit))
|
||||
.layer(timeout())
|
||||
.handle_error(handle_error::<BoxError>);
|
||||
|
||||
|
@ -194,7 +198,8 @@ fn layered() {
|
|||
|
||||
#[tokio::test] // async because of `.boxed()`
|
||||
async fn layered_boxed() {
|
||||
let app = route::<_, Body>("/echo", get(unit))
|
||||
let app = Router::new()
|
||||
.route::<_, Body>("/echo", get(unit))
|
||||
.layer(timeout())
|
||||
.boxed()
|
||||
.handle_error(handle_error::<BoxError>);
|
||||
|
|
113
src/tests/mod.rs
113
src/tests/mod.rs
|
@ -4,10 +4,8 @@ use crate::{
|
|||
extract,
|
||||
handler::{any, delete, get, on, patch, post, Handler},
|
||||
response::IntoResponse,
|
||||
route,
|
||||
routing::nest,
|
||||
routing::MethodFilter,
|
||||
service,
|
||||
service, Router,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use futures_util::future::Ready;
|
||||
|
@ -46,7 +44,9 @@ async fn hello_world() {
|
|||
"users#create"
|
||||
}
|
||||
|
||||
let app = route("/", get(root).post(foo)).route("/users", post(users_create));
|
||||
let app = Router::new()
|
||||
.route("/", get(root).post(foo))
|
||||
.route("/users", post(users_create));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -75,7 +75,7 @@ async fn hello_world() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn consume_body() {
|
||||
let app = route("/", get(|body: String| async { body }));
|
||||
let app = Router::new().route("/", get(|body: String| async { body }));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -98,7 +98,7 @@ async fn deserialize_body() {
|
|||
foo: String,
|
||||
}
|
||||
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
post(|input: extract::Json<Input>| async { input.0.foo }),
|
||||
);
|
||||
|
@ -124,7 +124,7 @@ async fn consume_body_to_json_requires_json_content_type() {
|
|||
foo: String,
|
||||
}
|
||||
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
post(|input: extract::Json<Input>| async { input.0.foo }),
|
||||
);
|
||||
|
@ -156,7 +156,7 @@ async fn body_with_length_limit() {
|
|||
|
||||
const LIMIT: u64 = 8;
|
||||
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
post(|_body: extract::ContentLengthLimit<Bytes, LIMIT>| async {}),
|
||||
);
|
||||
|
@ -202,16 +202,17 @@ async fn body_with_length_limit() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn routing() {
|
||||
let app = route(
|
||||
"/users",
|
||||
get(|_: Request<Body>| async { "users#index" })
|
||||
.post(|_: Request<Body>| async { "users#create" }),
|
||||
)
|
||||
.route("/users/:id", get(|_: Request<Body>| async { "users#show" }))
|
||||
.route(
|
||||
"/users/:id/action",
|
||||
get(|_: Request<Body>| async { "users#action" }),
|
||||
);
|
||||
let app = Router::new()
|
||||
.route(
|
||||
"/users",
|
||||
get(|_: Request<Body>| async { "users#index" })
|
||||
.post(|_: Request<Body>| async { "users#create" }),
|
||||
)
|
||||
.route("/users/:id", get(|_: Request<Body>| async { "users#show" }))
|
||||
.route(
|
||||
"/users/:id/action",
|
||||
get(|_: Request<Body>| async { "users#action" }),
|
||||
);
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -255,7 +256,7 @@ async fn routing() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn extracting_url_params() {
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/users/:id",
|
||||
get(|extract::Path(id): extract::Path<i32>| async move {
|
||||
assert_eq!(id, 42);
|
||||
|
@ -288,7 +289,7 @@ async fn extracting_url_params() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn extracting_url_params_multiple_times() {
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/users/:id",
|
||||
get(|_: extract::Path<i32>, _: extract::Path<String>| async {}),
|
||||
);
|
||||
|
@ -307,17 +308,18 @@ async fn extracting_url_params_multiple_times() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn boxing() {
|
||||
let app = route(
|
||||
"/",
|
||||
on(MethodFilter::GET, |_: Request<Body>| async {
|
||||
"hi from GET"
|
||||
})
|
||||
.on(MethodFilter::POST, |_: Request<Body>| async {
|
||||
"hi from POST"
|
||||
}),
|
||||
)
|
||||
.layer(tower_http::compression::CompressionLayer::new())
|
||||
.boxed();
|
||||
let app = Router::new()
|
||||
.route(
|
||||
"/",
|
||||
on(MethodFilter::GET, |_: Request<Body>| async {
|
||||
"hi from GET"
|
||||
})
|
||||
.on(MethodFilter::POST, |_: Request<Body>| async {
|
||||
"hi from POST"
|
||||
}),
|
||||
)
|
||||
.layer(tower_http::compression::CompressionLayer::new())
|
||||
.boxed();
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -345,22 +347,23 @@ async fn routing_between_services() {
|
|||
"handler"
|
||||
}
|
||||
|
||||
let app = route(
|
||||
"/one",
|
||||
service::get(service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::from("one get")))
|
||||
}))
|
||||
.post(service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::from("one post")))
|
||||
}))
|
||||
.on(
|
||||
MethodFilter::PUT,
|
||||
service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::from("one put")))
|
||||
}),
|
||||
),
|
||||
)
|
||||
.route("/two", service::on(MethodFilter::GET, any(handle)));
|
||||
let app = Router::new()
|
||||
.route(
|
||||
"/one",
|
||||
service::get(service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::from("one get")))
|
||||
}))
|
||||
.post(service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::from("one post")))
|
||||
}))
|
||||
.on(
|
||||
MethodFilter::PUT,
|
||||
service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::from("one put")))
|
||||
}),
|
||||
),
|
||||
)
|
||||
.route("/two", service::on(MethodFilter::GET, any(handle)));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -408,7 +411,7 @@ async fn middleware_on_single_route() {
|
|||
"Hello, World!"
|
||||
}
|
||||
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
get(handle.layer(
|
||||
ServiceBuilder::new()
|
||||
|
@ -432,7 +435,7 @@ async fn service_in_bottom() {
|
|||
Ok(Response::new(hyper::Body::empty()))
|
||||
}
|
||||
|
||||
let app = route("/", service::get(service_fn(handler)));
|
||||
let app = Router::new().route("/", service::get(service_fn(handler)));
|
||||
|
||||
run_in_background(app).await;
|
||||
}
|
||||
|
@ -466,7 +469,7 @@ async fn test_extractor_middleware() {
|
|||
|
||||
async fn handler() {}
|
||||
|
||||
let app = route(
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
get(handler.layer(extract::extractor_middleware::<RequireAuth>())),
|
||||
);
|
||||
|
@ -493,7 +496,9 @@ async fn test_extractor_middleware() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn wrong_method_handler() {
|
||||
let app = route("/", get(|| async {}).post(|| async {})).route("/foo", patch(|| async {}));
|
||||
let app = Router::new()
|
||||
.route("/", get(|| async {}).post(|| async {}))
|
||||
.route("/foo", patch(|| async {}));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -547,7 +552,9 @@ async fn wrong_method_service() {
|
|||
}
|
||||
}
|
||||
|
||||
let app = route("/", service::get(Svc).post(Svc)).route("/foo", service::patch(Svc));
|
||||
let app = Router::new()
|
||||
.route("/", service::get(Svc).post(Svc))
|
||||
.route("/foo", service::patch(Svc));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -588,7 +595,7 @@ async fn multiple_methods_for_one_handler() {
|
|||
"Hello, World!"
|
||||
}
|
||||
|
||||
let app = route("/", on(MethodFilter::GET | MethodFilter::POST, root));
|
||||
let app = Router::new().route("/", on(MethodFilter::GET | MethodFilter::POST, root));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
|
|
@ -4,36 +4,39 @@ use std::collections::HashMap;
|
|||
|
||||
#[tokio::test]
|
||||
async fn nesting_apps() {
|
||||
let api_routes = route(
|
||||
"/users",
|
||||
get(|| async { "users#index" }).post(|| async { "users#create" }),
|
||||
)
|
||||
.route(
|
||||
"/users/:id",
|
||||
get(
|
||||
|params: extract::Path<HashMap<String, String>>| async move {
|
||||
format!(
|
||||
"{}: users#show ({})",
|
||||
params.get("version").unwrap(),
|
||||
params.get("id").unwrap()
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
.route(
|
||||
"/games/:id",
|
||||
get(
|
||||
|params: extract::Path<HashMap<String, String>>| async move {
|
||||
format!(
|
||||
"{}: games#show ({})",
|
||||
params.get("version").unwrap(),
|
||||
params.get("id").unwrap()
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
let api_routes = Router::new()
|
||||
.route(
|
||||
"/users",
|
||||
get(|| async { "users#index" }).post(|| async { "users#create" }),
|
||||
)
|
||||
.route(
|
||||
"/users/:id",
|
||||
get(
|
||||
|params: extract::Path<HashMap<String, String>>| async move {
|
||||
format!(
|
||||
"{}: users#show ({})",
|
||||
params.get("version").unwrap(),
|
||||
params.get("id").unwrap()
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
.route(
|
||||
"/games/:id",
|
||||
get(
|
||||
|params: extract::Path<HashMap<String, String>>| async move {
|
||||
format!(
|
||||
"{}: games#show ({})",
|
||||
params.get("version").unwrap(),
|
||||
params.get("id").unwrap()
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
let app = route("/", get(|| async { "hi" })).nest("/:version/api", api_routes);
|
||||
let app = Router::new()
|
||||
.route("/", get(|| async { "hi" }))
|
||||
.nest("/:version/api", api_routes);
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -74,8 +77,8 @@ async fn nesting_apps() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn wrong_method_nest() {
|
||||
let nested_app = route("/", get(|| async {}));
|
||||
let app = crate::routing::nest("/", nested_app);
|
||||
let nested_app = Router::new().route("/", get(|| async {}));
|
||||
let app = Router::new().nest("/", nested_app);
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -101,7 +104,7 @@ async fn wrong_method_nest() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn nesting_at_root() {
|
||||
let app = nest("/", get(|uri: Uri| async move { uri.to_string() }));
|
||||
let app = Router::new().nest("/", get(|uri: Uri| async move { uri.to_string() }));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -130,14 +133,16 @@ async fn nesting_at_root() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn nested_url_extractor() {
|
||||
let app = nest(
|
||||
let app = Router::new().nest(
|
||||
"/foo",
|
||||
nest(
|
||||
Router::new().nest(
|
||||
"/bar",
|
||||
route("/baz", get(|uri: Uri| async move { uri.to_string() })).route(
|
||||
"/qux",
|
||||
get(|req: Request<Body>| async move { req.uri().to_string() }),
|
||||
),
|
||||
Router::new()
|
||||
.route("/baz", get(|uri: Uri| async move { uri.to_string() }))
|
||||
.route(
|
||||
"/qux",
|
||||
get(|req: Request<Body>| async move { req.uri().to_string() }),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -164,11 +169,11 @@ async fn nested_url_extractor() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn nested_url_original_extractor() {
|
||||
let app = nest(
|
||||
let app = Router::new().nest(
|
||||
"/foo",
|
||||
nest(
|
||||
Router::new().nest(
|
||||
"/bar",
|
||||
route(
|
||||
Router::new().route(
|
||||
"/baz",
|
||||
get(|uri: extract::OriginalUri| async move { uri.0.to_string() }),
|
||||
),
|
||||
|
@ -190,11 +195,11 @@ async fn nested_url_original_extractor() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn nested_service_sees_stripped_uri() {
|
||||
let app = nest(
|
||||
let app = Router::new().nest(
|
||||
"/foo",
|
||||
nest(
|
||||
Router::new().nest(
|
||||
"/bar",
|
||||
route(
|
||||
Router::new().route(
|
||||
"/baz",
|
||||
service_fn(|req: Request<Body>| async move {
|
||||
let body = box_body(Body::from(req.uri().to_string()));
|
||||
|
@ -219,7 +224,7 @@ async fn nested_service_sees_stripped_uri() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn nest_static_file_server() {
|
||||
let app = nest(
|
||||
let app = Router::new().nest(
|
||||
"/static",
|
||||
service::get(tower_http::services::ServeDir::new(".")).handle_error(|error| {
|
||||
Ok::<_, Infallible>((
|
||||
|
|
110
src/tests/or.rs
110
src/tests/or.rs
|
@ -7,8 +7,10 @@ use super::*;
|
|||
|
||||
#[tokio::test]
|
||||
async fn basic() {
|
||||
let one = route("/foo", get(|| async {})).route("/bar", get(|| async {}));
|
||||
let two = route("/baz", get(|| async {}));
|
||||
let one = Router::new()
|
||||
.route("/foo", get(|| async {}))
|
||||
.route("/bar", get(|| async {}));
|
||||
let two = Router::new().route("/baz", get(|| async {}));
|
||||
let app = one.or(two);
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
@ -46,10 +48,10 @@ async fn basic() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn multiple_ors_balanced_differently() {
|
||||
let one = route("/one", get(|| async { "one" }));
|
||||
let two = route("/two", get(|| async { "two" }));
|
||||
let three = route("/three", get(|| async { "three" }));
|
||||
let four = route("/four", get(|| async { "four" }));
|
||||
let one = Router::new().route("/one", get(|| async { "one" }));
|
||||
let two = Router::new().route("/two", get(|| async { "two" }));
|
||||
let three = Router::new().route("/three", get(|| async { "three" }));
|
||||
let four = Router::new().route("/four", get(|| async { "four" }));
|
||||
|
||||
test(
|
||||
"one",
|
||||
|
@ -105,8 +107,10 @@ async fn multiple_ors_balanced_differently() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn or_nested_inside_other_thing() {
|
||||
let inner = route("/bar", get(|| async {})).or(route("/baz", get(|| async {})));
|
||||
let app = nest("/foo", inner);
|
||||
let inner = Router::new()
|
||||
.route("/bar", get(|| async {}))
|
||||
.or(Router::new().route("/baz", get(|| async {})));
|
||||
let app = Router::new().nest("/foo", inner);
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -129,8 +133,8 @@ async fn or_nested_inside_other_thing() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn or_with_route_following() {
|
||||
let one = route("/one", get(|| async { "one" }));
|
||||
let two = route("/two", get(|| async { "two" }));
|
||||
let one = Router::new().route("/one", get(|| async { "one" }));
|
||||
let two = Router::new().route("/two", get(|| async { "two" }));
|
||||
let app = one.or(two).route("/three", get(|| async { "three" }));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
@ -161,8 +165,10 @@ async fn or_with_route_following() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn layer() {
|
||||
let one = route("/foo", get(|| async {}));
|
||||
let two = route("/bar", get(|| async {})).layer(ConcurrencyLimitLayer::new(10));
|
||||
let one = Router::new().route("/foo", get(|| async {}));
|
||||
let two = Router::new()
|
||||
.route("/bar", get(|| async {}))
|
||||
.layer(ConcurrencyLimitLayer::new(10));
|
||||
let app = one.or(two);
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
@ -186,8 +192,9 @@ async fn layer() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn layer_and_handle_error() {
|
||||
let one = route("/foo", get(|| async {}));
|
||||
let two = route("/time-out", get(futures::future::pending::<()>))
|
||||
let one = Router::new().route("/foo", get(|| async {}));
|
||||
let two = Router::new()
|
||||
.route("/time-out", get(futures::future::pending::<()>))
|
||||
.layer(TimeoutLayer::new(Duration::from_millis(10)))
|
||||
.handle_error(|_| Ok(StatusCode::REQUEST_TIMEOUT));
|
||||
let app = one.or(two);
|
||||
|
@ -206,8 +213,8 @@ async fn layer_and_handle_error() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn nesting() {
|
||||
let one = route("/foo", get(|| async {}));
|
||||
let two = nest("/bar", route("/baz", get(|| async {})));
|
||||
let one = Router::new().route("/foo", get(|| async {}));
|
||||
let two = Router::new().nest("/bar", Router::new().route("/baz", get(|| async {})));
|
||||
let app = one.or(two);
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
@ -224,8 +231,8 @@ async fn nesting() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn boxed() {
|
||||
let one = route("/foo", get(|| async {})).boxed();
|
||||
let two = route("/bar", get(|| async {})).boxed();
|
||||
let one = Router::new().route("/foo", get(|| async {})).boxed();
|
||||
let two = Router::new().route("/bar", get(|| async {})).boxed();
|
||||
let app = one.or(two);
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
@ -242,13 +249,14 @@ async fn boxed() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn many_ors() {
|
||||
let app = route("/r1", get(|| async {}))
|
||||
.or(route("/r2", get(|| async {})))
|
||||
.or(route("/r3", get(|| async {})))
|
||||
.or(route("/r4", get(|| async {})))
|
||||
.or(route("/r5", get(|| async {})))
|
||||
.or(route("/r6", get(|| async {})))
|
||||
.or(route("/r7", get(|| async {})));
|
||||
let app = Router::new()
|
||||
.route("/r1", get(|| async {}))
|
||||
.or(Router::new().route("/r2", get(|| async {})))
|
||||
.or(Router::new().route("/r3", get(|| async {})))
|
||||
.or(Router::new().route("/r4", get(|| async {})))
|
||||
.or(Router::new().route("/r5", get(|| async {})))
|
||||
.or(Router::new().route("/r6", get(|| async {})))
|
||||
.or(Router::new().route("/r7", get(|| async {})));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -273,18 +281,19 @@ async fn many_ors() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn services() {
|
||||
let app = route(
|
||||
"/foo",
|
||||
crate::service::get(service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::empty()))
|
||||
})),
|
||||
)
|
||||
.or(route(
|
||||
"/bar",
|
||||
crate::service::get(service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::empty()))
|
||||
})),
|
||||
));
|
||||
let app = Router::new()
|
||||
.route(
|
||||
"/foo",
|
||||
crate::service::get(service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::empty()))
|
||||
})),
|
||||
)
|
||||
.or(Router::new().route(
|
||||
"/bar",
|
||||
crate::service::get(service_fn(|_: Request<Body>| async {
|
||||
Ok::<_, Infallible>(Response::new(Body::empty()))
|
||||
})),
|
||||
));
|
||||
|
||||
let addr = run_in_background(app).await;
|
||||
|
||||
|
@ -319,8 +328,8 @@ async fn all_the_uris(
|
|||
|
||||
#[tokio::test]
|
||||
async fn nesting_and_seeing_the_right_uri() {
|
||||
let one = nest("/foo", route("/bar", get(all_the_uris)));
|
||||
let two = route("/foo", get(all_the_uris));
|
||||
let one = Router::new().nest("/foo", Router::new().route("/bar", get(all_the_uris)));
|
||||
let two = Router::new().route("/foo", get(all_the_uris));
|
||||
|
||||
let addr = run_in_background(one.or(two)).await;
|
||||
|
||||
|
@ -359,8 +368,11 @@ async fn nesting_and_seeing_the_right_uri() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn nesting_and_seeing_the_right_uri_at_more_levels_of_nesting() {
|
||||
let one = nest("/foo", nest("/bar", route("/baz", get(all_the_uris))));
|
||||
let two = route("/foo", get(all_the_uris));
|
||||
let one = Router::new().nest(
|
||||
"/foo",
|
||||
Router::new().nest("/bar", Router::new().route("/baz", get(all_the_uris))),
|
||||
);
|
||||
let two = Router::new().route("/foo", get(all_the_uris));
|
||||
|
||||
let addr = run_in_background(one.or(two)).await;
|
||||
|
||||
|
@ -399,9 +411,12 @@ async fn nesting_and_seeing_the_right_uri_at_more_levels_of_nesting() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn nesting_and_seeing_the_right_uri_ors_with_nesting() {
|
||||
let one = nest("/foo", nest("/bar", route("/baz", get(all_the_uris))));
|
||||
let two = nest("/foo", route("/qux", get(all_the_uris)));
|
||||
let three = route("/foo", get(all_the_uris));
|
||||
let one = Router::new().nest(
|
||||
"/foo",
|
||||
Router::new().nest("/bar", Router::new().route("/baz", get(all_the_uris))),
|
||||
);
|
||||
let two = Router::new().nest("/foo", Router::new().route("/qux", get(all_the_uris)));
|
||||
let three = Router::new().route("/foo", get(all_the_uris));
|
||||
|
||||
let addr = run_in_background(one.or(two).or(three)).await;
|
||||
|
||||
|
@ -455,8 +470,11 @@ async fn nesting_and_seeing_the_right_uri_ors_with_nesting() {
|
|||
|
||||
#[tokio::test]
|
||||
async fn nesting_and_seeing_the_right_uri_ors_with_multi_segment_uris() {
|
||||
let one = nest("/foo", nest("/bar", route("/baz", get(all_the_uris))));
|
||||
let two = route("/foo/bar", get(all_the_uris));
|
||||
let one = Router::new().nest(
|
||||
"/foo",
|
||||
Router::new().nest("/bar", Router::new().route("/baz", get(all_the_uris))),
|
||||
);
|
||||
let two = Router::new().route("/foo/bar", get(all_the_uris));
|
||||
|
||||
let addr = run_in_background(one.or(two)).await;
|
||||
|
||||
|
|
Loading…
Reference in a new issue