# Crate Documentation **Version:** 0.8.7 **Format Version:** 56 # Module `axum` axum is a web application framework that focuses on ergonomics and modularity. # High-level features - Route requests to handlers with a macro-free API. - Declaratively parse requests using extractors. - Simple and predictable error handling model. - Generate responses with minimal boilerplate. - Take full advantage of the [`tower`] and [`tower-http`] ecosystem of middleware, services, and utilities. In particular, the last point is what sets `axum` apart from other frameworks. `axum` doesn't have its own middleware system but instead uses [`tower::Service`]. This means `axum` gets timeouts, tracing, compression, authorization, and more, for free. It also enables you to share middleware with applications written using [`hyper`] or [`tonic`]. # Compatibility axum is designed to work with [tokio] and [hyper]. Runtime and transport layer independence is not a goal, at least for the time being. # Example The "Hello, World!" of axum is: ```rust,no_run use axum::{ routing::get, Router, }; #[tokio::main] async fn main() { // build our application with a single route let app = Router::new().route("/", get(|| async { "Hello, World!" })); // run our app with hyper, listening globally on port 3000 let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); } ``` Note using `#[tokio::main]` requires you enable tokio's `macros` and `rt-multi-thread` features or just `full` to enable all features (`cargo add tokio --features macros,rt-multi-thread`). # Routing [`Router`] is used to set up which paths go to which services: ```rust use axum::{Router, routing::get}; // our router let app = Router::new() .route("/", get(root)) .route("/foo", get(get_foo).post(post_foo)) .route("/foo/bar", get(foo_bar)); // which calls one of these handlers async fn root() {} async fn get_foo() {} async fn post_foo() {} async fn foo_bar() {} # let _: Router = app; ``` See [`Router`] for more details on routing. # Handlers In axum a "handler" is an async function that accepts zero or more ["extractors"](crate::extract) as arguments and returns something that can be converted [into a response](crate::response). Handlers are where your application logic lives and axum applications are built by routing between handlers. [`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html See [`handler`](crate::handler) for more details on handlers. # Extractors An extractor is a type that implements [`FromRequest`] or [`FromRequestParts`]. Extractors are how you pick apart the incoming request to get the parts your handler needs. ```rust use axum::extract::{Path, Query, Json}; use std::collections::HashMap; // `Path` gives you the path parameters and deserializes them. async fn path(Path(user_id): Path) {} // `Query` gives you the query parameters and deserializes them. async fn query(Query(params): Query>) {} // Buffer the request body and deserialize it as JSON into a // `serde_json::Value`. `Json` supports any type that implements // `serde::Deserialize`. async fn json(Json(payload): Json) {} ``` See [`extract`](crate::extract) for more details on extractors. # Responses Anything that implements [`IntoResponse`] can be returned from handlers. ```rust,no_run use axum::{ body::Body, routing::get, response::Json, Router, }; use serde_json::{Value, json}; // `&'static str` becomes a `200 OK` with `content-type: text/plain; charset=utf-8` async fn plain_text() -> &'static str { "foo" } // `Json` gives a content-type of `application/json` and works with any type // that implements `serde::Serialize` async fn json() -> Json { Json(json!({ "data": 42 })) } let app = Router::new() .route("/plain_text", get(plain_text)) .route("/json", get(json)); # let _: Router = app; ``` See [`response`](crate::response) for more details on building responses. # Error handling axum aims to have a simple and predictable error handling model. That means it is simple to convert errors into responses and you are guaranteed that all errors are handled. See [`error_handling`] for more details on axum's error handling model and how to handle errors gracefully. # Middleware There are several different ways to write middleware for axum. See [`middleware`] for more details. # Sharing state with handlers It is common to share some state between handlers. For example, a pool of database connections or clients to other services may need to be shared. The four most common ways of doing that are: - Using the [`State`] extractor - Using request extensions - Using closure captures - Using task-local variables ## Using the [`State`] extractor ```rust,no_run use axum::{ extract::State, routing::get, Router, }; use std::sync::Arc; struct AppState { // ... } let shared_state = Arc::new(AppState { /* ... */ }); let app = Router::new() .route("/", get(handler)) .with_state(shared_state); async fn handler( State(state): State>, ) { // ... } # let _: Router = app; ``` You should prefer using [`State`] if possible since it's more type safe. The downside is that it's less dynamic than task-local variables and request extensions. See [`State`] for more details about accessing state. ## Using request extensions Another way to share state with handlers is using [`Extension`] as layer and extractor: ```rust,no_run use axum::{ extract::Extension, routing::get, Router, }; use std::sync::Arc; struct AppState { // ... } let shared_state = Arc::new(AppState { /* ... */ }); let app = Router::new() .route("/", get(handler)) .layer(Extension(shared_state)); async fn handler( Extension(state): Extension>, ) { // ... } # let _: Router = app; ``` The downside to this approach is that you'll get runtime errors (specifically a `500 Internal Server Error` response) if you try and extract an extension that doesn't exist, perhaps because you forgot to add the middleware or because you're extracting the wrong type. ## Using closure captures State can also be passed directly to handlers using closure captures: ```rust,no_run use axum::{ Json, extract::{Extension, Path}, routing::{get, post}, Router, }; use std::sync::Arc; use serde::Deserialize; struct AppState { // ... } let shared_state = Arc::new(AppState { /* ... */ }); let app = Router::new() .route( "/users", post({ let shared_state = Arc::clone(&shared_state); move |body| create_user(body, shared_state) }), ) .route( "/users/{id}", get({ let shared_state = Arc::clone(&shared_state); move |path| get_user(path, shared_state) }), ); async fn get_user(Path(user_id): Path, state: Arc) { // ... } async fn create_user(Json(payload): Json, state: Arc) { // ... } #[derive(Deserialize)] struct CreateUserPayload { // ... } # let _: Router = app; ``` The downside to this approach is that it's the most verbose approach. ## Using task-local variables This also allows to share state with `IntoResponse` implementations: ```rust,no_run use axum::{ extract::Request, http::{header, StatusCode}, middleware::{self, Next}, response::{IntoResponse, Response}, routing::get, Router, }; use tokio::task_local; #[derive(Clone)] struct CurrentUser { name: String, } task_local! { pub static USER: CurrentUser; } async fn auth(req: Request, next: Next) -> Result { let auth_header = req .headers() .get(header::AUTHORIZATION) .and_then(|header| header.to_str().ok()) .ok_or(StatusCode::UNAUTHORIZED)?; if let Some(current_user) = authorize_current_user(auth_header).await { // State is setup here in the middleware Ok(USER.scope(current_user, next.run(req)).await) } else { Err(StatusCode::UNAUTHORIZED) } } async fn authorize_current_user(auth_token: &str) -> Option { Some(CurrentUser { name: auth_token.to_string(), }) } struct UserResponse; impl IntoResponse for UserResponse { fn into_response(self) -> Response { // State is accessed here in the IntoResponse implementation let current_user = USER.with(|u| u.clone()); (StatusCode::OK, current_user.name).into_response() } } async fn handler() -> UserResponse { UserResponse } let app: Router = Router::new() .route("/", get(handler)) .route_layer(middleware::from_fn(auth)); ``` The main downside to this approach is that it only works when the async executor being used has the concept of task-local variables. The example above uses [tokio's `task_local` macro](https://docs.rs/tokio/1/tokio/macro.task_local.html). smol does not yet offer equivalent functionality at the time of writing (see [this GitHub issue](https://github.com/smol-rs/async-executor/issues/139)). # Building integrations for axum Libraries authors that want to provide [`FromRequest`], [`FromRequestParts`], or [`IntoResponse`] implementations should depend on the [`axum-core`] crate, instead of `axum` if possible. [`axum-core`] contains core types and traits and is less likely to receive breaking changes. # Required dependencies To use axum there are a few dependencies you have to pull in as well: ```toml [dependencies] axum = "" tokio = { version = "", features = ["full"] } tower = "" ``` The `"full"` feature for tokio isn't necessary but it's the easiest way to get started. Tower isn't strictly necessary either but helpful for testing. See the testing example in the repo to learn more about testing axum apps. # Examples The axum repo contains [a number of examples][examples] that show how to put all the pieces together. # Feature flags axum uses a set of [feature flags] to reduce the amount of compiled and optional dependencies. The following optional features are available: Name | Description | Default? ---|---|--- `http1` | Enables hyper's `http1` feature | `http2` | Enables hyper's `http2` feature | `json` | Enables the [`Json`] type and some similar convenience functionality | `macros` | Enables optional utility macros | `matched-path` | Enables capturing of every request's router path and the [`MatchedPath`] extractor | `multipart` | Enables parsing `multipart/form-data` requests with [`Multipart`] | `original-uri` | Enables capturing of every request's original URI and the [`OriginalUri`] extractor | `tokio` | Enables `tokio` as a dependency and `axum::serve`, `SSE` and `extract::connect_info` types. | `tower-log` | Enables `tower`'s `log` feature | `tracing` | Log rejections from built-in extractors | `ws` | Enables WebSockets support via [`extract::ws`] | `form` | Enables the `Form` extractor | `query` | Enables the `Query` extractor | [`MatchedPath`]: crate::extract::MatchedPath [`Multipart`]: crate::extract::Multipart [`OriginalUri`]: crate::extract::OriginalUri [`tower`]: https://crates.io/crates/tower [`tower-http`]: https://crates.io/crates/tower-http [`tokio`]: http://crates.io/crates/tokio [`hyper`]: http://crates.io/crates/hyper [`tonic`]: http://crates.io/crates/tonic [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html#the-features-section [`IntoResponse`]: crate::response::IntoResponse [`Timeout`]: tower::timeout::Timeout [examples]: https://github.com/tokio-rs/axum/tree/main/examples [`Router::merge`]: crate::routing::Router::merge [`Service`]: tower::Service [`Service::poll_ready`]: tower::Service::poll_ready [`Service`'s]: tower::Service [`tower::Service`]: tower::Service [tower-guides]: https://github.com/tower-rs/tower/tree/master/guides [`Uuid`]: https://docs.rs/uuid/latest/uuid/ [`FromRequest`]: crate::extract::FromRequest [`FromRequestParts`]: crate::extract::FromRequestParts [`HeaderMap`]: http::header::HeaderMap [`Request`]: http::Request [customize-extractor-error]: https://github.com/tokio-rs/axum/blob/main/examples/customize-extractor-error/src/main.rs [axum-macros]: https://docs.rs/axum-macros [`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html [`Handler`]: crate::handler::Handler [`Infallible`]: std::convert::Infallible [load shed]: tower::load_shed [`axum-core`]: http://crates.io/crates/axum-core [`State`]: crate::extract::State ## Modules ## Module `body` HTTP body utilities. ```rust pub mod body { /* ... */ } ``` ### Functions #### Function `to_bytes` Converts [`Body`] into [`Bytes`] and limits the maximum size of the body. # Example ```rust use axum::body::{to_bytes, Body}; # async fn foo() -> Result<(), axum_core::Error> { let body = Body::from(vec![1, 2, 3]); // Use `usize::MAX` if you don't care about the maximum size. let bytes = to_bytes(body, usize::MAX).await?; assert_eq!(&bytes[..], &[1, 2, 3]); # Ok(()) # } ``` You can detect if the limit was hit by checking the source of the error: ```rust use axum::body::{to_bytes, Body}; use http_body_util::LengthLimitError; # #[tokio::main] # async fn main() { let body = Body::from(vec![1, 2, 3]); match to_bytes(body, 1).await { Ok(_bytes) => panic!("should have hit the limit"), Err(err) => { let source = std::error::Error::source(&err).unwrap(); assert!(source.is::()); } } # } ``` ```rust pub async fn to_bytes(body: Body, limit: usize) -> Result { /* ... */ } ``` ### Re-exports #### Re-export `Body` **Attributes:** - `Other("#[doc(no_inline)]")` ```rust pub use http_body::Body as HttpBody; ``` #### Re-export `Bytes` **Attributes:** - `Other("#[doc(no_inline)]")` ```rust pub use bytes::Bytes; ``` #### Re-export `Body` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::body::Body; ``` #### Re-export `BodyDataStream` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::body::BodyDataStream; ``` ## Module `error_handling` Error handling model and utilities # axum's error handling model axum is based on [`tower::Service`] which bundles errors through its associated `Error` type. If you have a [`Service`] that produces an error and that error makes it all the way up to hyper, the connection will be terminated _without_ sending a response. This is generally not desirable so axum makes sure you always produce a response by relying on the type system. axum does this by requiring all services have [`Infallible`] as their error type. `Infallible` is the error type for errors that can never happen. This means if you define a handler like: ```rust use axum::http::StatusCode; async fn handler() -> Result { # todo!() // ... } ``` While it looks like it might fail with a `StatusCode` this actually isn't an "error". If this handler returns `Err(some_status_code)` that will still be converted into a [`Response`] and sent back to the client. This is done through `StatusCode`'s [`IntoResponse`] implementation. It doesn't matter whether you return `Err(StatusCode::NOT_FOUND)` or `Err(StatusCode::INTERNAL_SERVER_ERROR)`. These are not considered errors in axum. Instead of a direct `StatusCode`, it makes sense to use intermediate error type that can ultimately be converted to `Response`. This allows using `?` operator in handlers. See those examples: * [`anyhow-error-response`][anyhow] for generic boxed errors * [`error-handling`][error-handling] for application-specific detailed errors [anyhow]: https://github.com/tokio-rs/axum/blob/main/examples/anyhow-error-response/src/main.rs [error-handling]: https://github.com/tokio-rs/axum/blob/main/examples/error-handling/src/main.rs This also applies to extractors. If an extractor doesn't match the request the request will be rejected and a response will be returned without calling your handler. See [`extract`](crate::extract) to learn more about handling extractor failures. # Routing to fallible services You generally don't have to think about errors if you're only using async functions as handlers. However if you're embedding general `Service`s or applying middleware, which might produce errors you have to tell axum how to convert those errors into responses. ```rust use axum::{ Router, body::Body, http::{Request, Response, StatusCode}, error_handling::HandleError, }; async fn thing_that_might_fail() -> Result<(), anyhow::Error> { # Ok(()) // ... } // this service might fail with `anyhow::Error` let some_fallible_service = tower::service_fn(|_req| async { thing_that_might_fail().await?; Ok::<_, anyhow::Error>(Response::new(Body::empty())) }); let app = Router::new().route_service( "/", // we cannot route to `some_fallible_service` directly since it might fail. // we have to use `handle_error` which converts its errors into responses // and changes its error type from `anyhow::Error` to `Infallible`. HandleError::new(some_fallible_service, handle_anyhow_error), ); // handle errors by converting them into something that implements // `IntoResponse` async fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) { ( StatusCode::INTERNAL_SERVER_ERROR, format!("Something went wrong: {err}"), ) } # let _: Router = app; ``` # Applying fallible middleware Similarly axum requires you to handle errors from middleware. That is done with [`HandleErrorLayer`]: ```rust use axum::{ Router, BoxError, routing::get, http::StatusCode, error_handling::HandleErrorLayer, }; use std::time::Duration; use tower::ServiceBuilder; let app = Router::new() .route("/", get(|| async {})) .layer( ServiceBuilder::new() // `timeout` will produce an error if the handler takes // too long so we must handle those .layer(HandleErrorLayer::new(handle_timeout_error)) .timeout(Duration::from_secs(30)) ); async fn handle_timeout_error(err: BoxError) -> (StatusCode, String) { if err.is::() { ( StatusCode::REQUEST_TIMEOUT, "Request took too long".to_string(), ) } else { ( StatusCode::INTERNAL_SERVER_ERROR, format!("Unhandled internal error: {err}"), ) } } # let _: Router = app; ``` # Running extractors for error handling `HandleErrorLayer` also supports running extractors: ```rust use axum::{ Router, BoxError, routing::get, http::{StatusCode, Method, Uri}, error_handling::HandleErrorLayer, }; use std::time::Duration; use tower::ServiceBuilder; let app = Router::new() .route("/", get(|| async {})) .layer( ServiceBuilder::new() // `timeout` will produce an error if the handler takes // too long so we must handle those .layer(HandleErrorLayer::new(handle_timeout_error)) .timeout(Duration::from_secs(30)) ); async fn handle_timeout_error( // `Method` and `Uri` are extractors so they can be used here method: Method, uri: Uri, // the last argument must be the error itself err: BoxError, ) -> (StatusCode, String) { ( StatusCode::INTERNAL_SERVER_ERROR, format!("`{method} {uri}` failed with {err}"), ) } # let _: Router = app; ``` [`tower::Service`]: `tower::Service` [`Infallible`]: std::convert::Infallible [`Response`]: crate::response::Response [`IntoResponse`]: crate::response::IntoResponse ```rust pub mod error_handling { /* ... */ } ``` ### Modules ## Module `future` Future types. ```rust pub mod future { /* ... */ } ``` ### Types #### Struct `HandleErrorFuture` Response future for [`HandleError`]. ```rust pub struct HandleErrorFuture { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Future** - ```rust fn poll(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<::Output> { /* ... */ } ``` - **FutureExt** - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoFuture** - ```rust fn into_future(self: Self) -> ::IntoFuture { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryFuture** - ```rust fn try_poll(self: Pin<&mut F>, cx: &mut Context<''_>) -> Poll<::Output> { /* ... */ } ``` - **TryFutureExt** - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Types #### Struct `HandleErrorLayer` [`Layer`] that applies [`HandleError`] which is a [`Service`] adapter that handles errors by converting them into responses. See [module docs](self) for more details on axum's error handling model. ```rust pub struct HandleErrorLayer { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn new(f: F) -> Self { /* ... */ } ``` Create a new `HandleErrorLayer`. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Self { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **Layer** - ```rust fn layer(self: &Self, inner: S) -> ::Service { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `HandleError` A [`Service`] adapter that handles errors by converting them into responses. See [module docs](self) for more details on axum's error handling model. ```rust pub struct HandleError { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn new(inner: S, f: F) -> Self { /* ... */ } ``` Create a new `HandleError`. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Self { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **MakeService** - ```rust fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll>::MakeError>> { /* ... */ } ``` - ```rust fn make_service(self: &mut Self, target: Target) -> >::Future { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **Service** - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - **ServiceExt** - ```rust fn into_make_service(self: Self) -> IntoMakeService { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo { /* ... */ } ``` - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ## Module `extract` Types and traits for extracting data from requests. # Intro A handler function is an async function that takes any number of "extractors" as arguments. An extractor is a type that implements [`FromRequest`] or [`FromRequestParts`]. For example, [`Json`] is an extractor that consumes the request body and deserializes it as JSON into some target type: ```rust,no_run use axum::{ extract::Json, routing::post, handler::Handler, Router, }; use serde::Deserialize; #[derive(Deserialize)] struct CreateUser { email: String, password: String, } async fn create_user(Json(payload): Json) { // ... } let app = Router::new().route("/users", post(create_user)); # let _: Router = app; ``` # Common extractors Some commonly used extractors are: ```rust,no_run use axum::{ extract::{Request, Json, Path, Extension, Query}, routing::post, http::header::HeaderMap, body::{Bytes, Body}, Router, }; use serde_json::Value; use std::collections::HashMap; // `Path` gives you the path parameters and deserializes them. See its docs for // more details async fn path(Path(user_id): Path) {} // `Query` gives you the query parameters and deserializes them. async fn query(Query(params): Query>) {} // `HeaderMap` gives you all the headers async fn headers(headers: HeaderMap) {} // `String` consumes the request body and ensures it is valid utf-8 async fn string(body: String) {} // `Bytes` gives you the raw request body async fn bytes(body: Bytes) {} // We've already seen `Json` for parsing the request body as json async fn json(Json(payload): Json) {} // `Request` gives you the whole request for maximum control async fn request(request: Request) {} // `Extension` extracts data from "request extensions" // This is commonly used to share state with handlers async fn extension(Extension(state): Extension) {} #[derive(Clone)] struct State { /* ... */ } let app = Router::new() .route("/path/{user_id}", post(path)) .route("/query", post(query)) .route("/string", post(string)) .route("/bytes", post(bytes)) .route("/json", post(json)) .route("/request", post(request)) .route("/extension", post(extension)); # let _: Router = app; ``` # Applying multiple extractors You can also apply multiple extractors: ```rust,no_run use axum::{ extract::{Path, Query}, routing::get, Router, }; use uuid::Uuid; use serde::Deserialize; let app = Router::new().route("/users/{id}/things", get(get_user_things)); #[derive(Deserialize)] struct Pagination { page: usize, per_page: usize, } async fn get_user_things( Path(user_id): Path, Query(pagination): Query, ) { // ... } # let _: Router = app; ``` # The order of extractors Extractors always run in the order of the function parameters that is from left to right. The request body is an asynchronous stream that can only be consumed once. Therefore you can only have one extractor that consumes the request body. axum enforces this by requiring such extractors to be the _last_ argument your handler takes. For example ```rust use axum::{extract::State, http::{Method, HeaderMap}}; # # #[derive(Clone)] # struct AppState { # } async fn handler( // `Method` and `HeaderMap` don't consume the request body so they can // put anywhere in the argument list (but before `body`) method: Method, headers: HeaderMap, // `State` is also an extractor so it needs to be before `body` State(state): State, // `String` consumes the request body and thus must be the last extractor body: String, ) { // ... } # # let _: axum::routing::MethodRouter = axum::routing::get(handler); ``` We get a compile error if `String` isn't the last extractor: ```rust,compile_fail use axum::http::Method; async fn handler( // this doesn't work since `String` must be the last argument body: String, method: Method, ) { // ... } # # let _: axum::routing::MethodRouter = axum::routing::get(handler); ``` This also means you cannot consume the request body twice: ```rust,compile_fail use axum::Json; use serde::Deserialize; #[derive(Deserialize)] struct Payload {} async fn handler( // `String` and `Json` both consume the request body // so they cannot both be used string_body: String, json_body: Json, ) { // ... } # # let _: axum::routing::MethodRouter = axum::routing::get(handler); ``` axum enforces this by requiring the last extractor implements [`FromRequest`] and all others implement [`FromRequestParts`]. # Handling extractor rejections If you want to handle the case of an extractor failing within a specific handler, you can wrap it in `Result`, with the error being the rejection type of the extractor: ```rust,no_run use axum::{ extract::{Json, rejection::JsonRejection}, routing::post, Router, }; use serde_json::Value; async fn create_user(payload: Result, JsonRejection>) { match payload { Ok(payload) => { // We got a valid JSON payload } Err(JsonRejection::MissingJsonContentType(_)) => { // Request didn't have `Content-Type: application/json` // header } Err(JsonRejection::JsonDataError(_)) => { // Couldn't deserialize the body into the target type } Err(JsonRejection::JsonSyntaxError(_)) => { // Syntax error in the body } Err(JsonRejection::BytesRejection(_)) => { // Failed to extract the request body } Err(_) => { // `JsonRejection` is marked `#[non_exhaustive]` so match must // include a catch-all case. } } } let app = Router::new().route("/users", post(create_user)); # let _: Router = app; ``` # Optional extractors Some extractors implement [`OptionalFromRequestParts`] in addition to [`FromRequestParts`], or [`OptionalFromRequest`] in addition to [`FromRequest`]. These extractors can be used inside of `Option`. It depends on the particular `OptionalFromRequestParts` or `OptionalFromRequest` implementation what this does: For example for `TypedHeader` from axum-extra, you get `None` if the header you're trying to extract is not part of the request, but if the header is present and fails to parse, the request is rejected. ```rust,no_run use axum::{routing::post, Router}; use axum_extra::{headers::UserAgent, TypedHeader}; use serde_json::Value; async fn foo(user_agent: Option>) { if let Some(TypedHeader(user_agent)) = user_agent { // The client sent a user agent } else { // No user agent header } } let app = Router::new().route("/foo", post(foo)); # let _: Router = app; ``` # Customizing extractor responses If an extractor fails it will return a response with the error and your handler will not be called. To customize the error response you have two options: 1. Use `Result` as your extractor like shown in ["Handling extractor rejections"](#handling-extractor-rejections). This works well if you're only using the extractor in a single handler. 2. Create your own extractor that in its [`FromRequest`] implementation calls one of axum's built in extractors but returns a different response for rejections. See the [customize-extractor-error] example for more details. # Accessing inner errors axum's built-in extractors don't directly expose the inner error. This gives us more flexibility and allows us to change internal implementations without breaking the public API. For example that means while [`Json`] is implemented using [`serde_json`] it doesn't directly expose the [`serde_json::Error`] that's contained in [`JsonRejection::JsonDataError`]. However it is still possible to access via methods from [`std::error::Error`]: ```rust use std::error::Error; use axum::{ extract::{Json, rejection::JsonRejection}, response::IntoResponse, http::StatusCode, }; use serde_json::{json, Value}; async fn handler( result: Result, JsonRejection>, ) -> Result, (StatusCode, String)> { match result { // if the client sent valid JSON then we're good Ok(Json(payload)) => Ok(Json(json!({ "payload": payload }))), Err(err) => match err { JsonRejection::JsonDataError(err) => { Err(serde_json_error_response(err)) } JsonRejection::JsonSyntaxError(err) => { Err(serde_json_error_response(err)) } // handle other rejections from the `Json` extractor JsonRejection::MissingJsonContentType(_) => Err(( StatusCode::BAD_REQUEST, "Missing `Content-Type: application/json` header".to_string(), )), JsonRejection::BytesRejection(_) => Err(( StatusCode::INTERNAL_SERVER_ERROR, "Failed to buffer request body".to_string(), )), // we must provide a catch-all case since `JsonRejection` is marked // `#[non_exhaustive]` _ => Err(( StatusCode::INTERNAL_SERVER_ERROR, "Unknown error".to_string(), )), }, } } // attempt to extract the inner `serde_path_to_error::Error`, // if that succeeds we can provide a more specific error. // // `Json` uses `serde_path_to_error` so the error will be wrapped in `serde_path_to_error::Error`. fn serde_json_error_response(err: E) -> (StatusCode, String) where E: Error + 'static, { if let Some(err) = find_error_source::>(&err) { let serde_json_err = err.inner(); ( StatusCode::BAD_REQUEST, format!( "Invalid JSON at line {} column {}", serde_json_err.line(), serde_json_err.column() ), ) } else { (StatusCode::BAD_REQUEST, "Unknown error".to_string()) } } // attempt to downcast `err` into a `T` and if that fails recursively try and // downcast `err`'s source fn find_error_source<'a, T>(err: &'a (dyn Error + 'static)) -> Option<&'a T> where T: Error + 'static, { if let Some(err) = err.downcast_ref::() { Some(err) } else if let Some(source) = err.source() { find_error_source(source) } else { None } } # # #[tokio::main] # async fn main() { # use axum::extract::FromRequest; # # let req = axum::http::Request::builder() # .header("content-type", "application/json") # .body(axum::body::Body::from("{")) # .unwrap(); # # let err = match Json::::from_request(req, &()).await.unwrap_err() { # JsonRejection::JsonSyntaxError(err) => err, # _ => panic!(), # }; # # let (_, body) = serde_json_error_response(err); # assert_eq!(body, "Invalid JSON at line 1 column 1"); # } ``` Note that while this approach works it might break in the future if axum changes its implementation to use a different error type internally. Such changes might happen without major breaking versions. # Defining custom extractors You can also define your own extractors by implementing either [`FromRequestParts`] or [`FromRequest`]. ## Implementing `FromRequestParts` Implement `FromRequestParts` if your extractor doesn't need access to the request body: ```rust,no_run use axum::{ extract::FromRequestParts, routing::get, Router, http::{ StatusCode, header::{HeaderValue, USER_AGENT}, request::Parts, }, }; struct ExtractUserAgent(HeaderValue); impl FromRequestParts for ExtractUserAgent where S: Send + Sync, { type Rejection = (StatusCode, &'static str); async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { if let Some(user_agent) = parts.headers.get(USER_AGENT) { Ok(ExtractUserAgent(user_agent.clone())) } else { Err((StatusCode::BAD_REQUEST, "`User-Agent` header is missing")) } } } async fn handler(ExtractUserAgent(user_agent): ExtractUserAgent) { // ... } let app = Router::new().route("/foo", get(handler)); # let _: Router = app; ``` ## Implementing `FromRequest` If your extractor needs to consume the request body you must implement [`FromRequest`] ```rust,no_run use axum::{ extract::{Request, FromRequest}, response::{Response, IntoResponse}, body::{Bytes, Body}, routing::get, Router, http::{ StatusCode, header::{HeaderValue, USER_AGENT}, }, }; struct ValidatedBody(Bytes); impl FromRequest for ValidatedBody where Bytes: FromRequest, S: Send + Sync, { type Rejection = Response; async fn from_request(req: Request, state: &S) -> Result { let body = Bytes::from_request(req, state) .await .map_err(IntoResponse::into_response)?; // do validation... Ok(Self(body)) } } async fn handler(ValidatedBody(body): ValidatedBody) { // ... } let app = Router::new().route("/foo", get(handler)); # let _: Router = app; ``` ## Cannot implement both `FromRequest` and `FromRequestParts` Note that you will make your extractor unusable by implementing both `FromRequest` and `FromRequestParts` directly for the same type, unless it is wrapping another extractor: ```rust,compile_fail use axum::{ Router, routing::get, extract::{FromRequest, Request, FromRequestParts}, http::request::Parts, body::Body, }; use std::convert::Infallible; // Some extractor that doesn't wrap another extractor struct MyExtractor; // `MyExtractor` implements both `FromRequest` impl FromRequest for MyExtractor where S: Send + Sync, { type Rejection = Infallible; async fn from_request(req: Request, state: &S) -> Result { // ... # todo!() } } // and `FromRequestParts` impl FromRequestParts for MyExtractor where S: Send + Sync, { type Rejection = Infallible; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { // ... # todo!() } } let app = Router::new().route( "/", // This fails when we go to actually use `MyExtractor` in a handler function. // This is due to a limit in Rust's type system. // // The workaround is to implement either `FromRequest` or `FromRequestParts` // but not both, if your extractor doesn't wrap another extractor. // // See "Wrapping extractors" for how to wrap other extractors. get(|_: MyExtractor| async {}), ); # let _: Router = app; ``` # Accessing other extractors in `FromRequest` or `FromRequestParts` implementations When defining custom extractors you often need to access another extractor in your implementation. ```rust use axum::{ extract::{Extension, FromRequestParts}, http::{StatusCode, HeaderMap, request::Parts}, response::{IntoResponse, Response}, routing::get, Router, }; #[derive(Clone)] struct State { // ... } struct AuthenticatedUser { // ... } impl FromRequestParts for AuthenticatedUser where S: Send + Sync, { type Rejection = Response; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { // You can either call them directly... let headers = HeaderMap::from_request_parts(parts, state) .await .map_err(|err| match err {})?; // ... or use `extract` / `extract_with_state` from `RequestExt` / `RequestPartsExt` use axum::RequestPartsExt; let Extension(state) = parts.extract::>() .await .map_err(|err| err.into_response())?; unimplemented!("actually perform the authorization") } } async fn handler(user: AuthenticatedUser) { // ... } let state = State { /* ... */ }; let app = Router::new().route("/", get(handler)).layer(Extension(state)); # let _: Router = app; ``` # Request body limits For security reasons, [`Bytes`] will, by default, not accept bodies larger than 2MB. This also applies to extractors that uses [`Bytes`] internally such as `String`, [`Json`], and [`Form`]. For more details, including how to disable this limit, see [`DefaultBodyLimit`]. # Wrapping extractors If you want to write an extractor that generically wraps another extractor (that may or may not consume the request body) you should implement both [`FromRequest`] and [`FromRequestParts`]: ```rust use axum::{ Router, body::Body, routing::get, extract::{Request, FromRequest, FromRequestParts}, http::{HeaderMap, request::Parts}, }; use std::time::{Instant, Duration}; // an extractor that wraps another and measures how long time it takes to run struct Timing { extractor: E, duration: Duration, } // we must implement both `FromRequestParts` impl FromRequestParts for Timing where S: Send + Sync, T: FromRequestParts, { type Rejection = T::Rejection; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let start = Instant::now(); let extractor = T::from_request_parts(parts, state).await?; let duration = start.elapsed(); Ok(Timing { extractor, duration, }) } } // and `FromRequest` impl FromRequest for Timing where S: Send + Sync, T: FromRequest, { type Rejection = T::Rejection; async fn from_request(req: Request, state: &S) -> Result { let start = Instant::now(); let extractor = T::from_request(req, state).await?; let duration = start.elapsed(); Ok(Timing { extractor, duration, }) } } async fn handler( // this uses the `FromRequestParts` impl _: Timing, // this uses the `FromRequest` impl _: Timing, ) {} # let _: axum::routing::MethodRouter = axum::routing::get(handler); ``` # Logging rejections All built-in extractors will log rejections for easier debugging. To see the logs, enable the `tracing` feature for axum (enabled by default) and the `axum::rejection=trace` tracing target, for example with `RUST_LOG=info,axum::rejection=trace cargo run`. [axum-extra]: https://docs.rs/axum-extra/latest/axum_extra/extract/index.html [`body::Body`]: crate::body::Body [`Bytes`]: crate::body::Bytes [customize-extractor-error]: https://github.com/tokio-rs/axum/blob/main/examples/customize-extractor-error/src/main.rs [`HeaderMap`]: https://docs.rs/http/latest/http/header/struct.HeaderMap.html [`Request`]: https://docs.rs/http/latest/http/struct.Request.html [`JsonRejection::JsonDataError`]: rejection::JsonRejection::JsonDataError ```rust pub mod extract { /* ... */ } ``` ### Modules ## Module `connect_info` **Attributes:** - `Other("#[(feature = \"tokio\")]")` Extractor for getting connection information from a client. See [`Router::into_make_service_with_connect_info`] for more details. [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info ```rust pub mod connect_info { /* ... */ } ``` ### Types #### Struct `IntoMakeServiceWithConnectInfo` A [`MakeService`] created from a router. See [`Router::into_make_service_with_connect_info`] for more details. [`MakeService`]: tower::make::MakeService [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info ```rust pub struct IntoMakeServiceWithConnectInfo { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Self { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **MakeService** - ```rust fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll>::MakeError>> { /* ... */ } ``` - ```rust fn make_service(self: &mut Self, target: Target) -> >::Future { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **Service** - ```rust fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, target: T) -> ::Future { /* ... */ } ``` - **ServiceExt** - ```rust fn into_make_service(self: Self) -> IntoMakeService { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo { /* ... */ } ``` - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `ResponseFuture` Response future for [`IntoMakeServiceWithConnectInfo`]. ```rust pub struct ResponseFuture { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Future** - ```rust fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<''_>) -> std::task::Poll<::Output> { /* ... */ } ``` - **FutureExt** - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoFuture** - ```rust fn into_future(self: Self) -> ::IntoFuture { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryFuture** - ```rust fn try_poll(self: Pin<&mut F>, cx: &mut Context<''_>) -> Poll<::Output> { /* ... */ } ``` - **TryFutureExt** - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `ConnectInfo` Extractor for getting connection information produced by a [`Connected`]. Note this extractor requires you to use [`Router::into_make_service_with_connect_info`] to run your app otherwise it will fail at runtime. See [`Router::into_make_service_with_connect_info`] for more details. [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info ```rust pub struct ConnectInfo(pub T); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `T` | | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> ConnectInfo { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Copy** - **CryptoRng** - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Deref** - ```rust fn deref(self: &Self) -> &::Target { /* ... */ } ``` - **DerefMut** - ```rust fn deref_mut(self: &mut Self) -> &mut ::Target { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **FromRequest** - ```rust fn from_request(req: Request, state: &S) -> impl Future>::Rejection>> { /* ... */ } ``` - **FromRequestParts** - ```rust async fn from_request_parts(parts: &mut Parts, state: &S) -> Result::Rejection> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **Receiver** - **RefUnwindSafe** - **Rng** - **RngCore** - ```rust fn next_u32(self: &mut Self) -> u32 { /* ... */ } ``` - ```rust fn next_u64(self: &mut Self) -> u64 { /* ... */ } ``` - ```rust fn fill_bytes(self: &mut Self, dst: &mut [u8]) { /* ... */ } ``` - **Same** - **Send** - **ServiceExt** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryCryptoRng** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **TryRngCore** - ```rust fn try_next_u32(self: &mut Self) -> Result::Error> { /* ... */ } ``` - ```rust fn try_next_u64(self: &mut Self) -> Result::Error> { /* ... */ } ``` - ```rust fn try_fill_bytes(self: &mut Self, dst: &mut [u8]) -> Result<(), ::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `MockConnectInfo` Middleware used to mock [`ConnectInfo`] during tests. If you're accidentally using [`MockConnectInfo`] and [`Router::into_make_service_with_connect_info`] at the same time then [`Router::into_make_service_with_connect_info`] takes precedence. # Example ``` use axum::{ Router, extract::connect_info::{MockConnectInfo, ConnectInfo}, body::Body, routing::get, http::{Request, StatusCode}, }; use std::net::SocketAddr; use tower::ServiceExt; async fn handler(ConnectInfo(addr): ConnectInfo) {} // this router you can run with `app.into_make_service_with_connect_info::()` fn app() -> Router { Router::new().route("/", get(handler)) } // use this router for tests fn test_app() -> Router { app().layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 1337)))) } // #[tokio::test] async fn some_test() { let app = test_app(); let request = Request::new(Body::empty()); let response = app.oneshot(request).await.unwrap(); assert_eq!(response.status(), StatusCode::OK); } # # #[tokio::main] # async fn main() { # some_test().await; # } ``` [`Router::into_make_service_with_connect_info`]: crate::Router::into_make_service_with_connect_info ```rust pub struct MockConnectInfo(pub T); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `T` | | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> MockConnectInfo { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Copy** - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **Layer** - ```rust fn layer(self: &Self, inner: S) -> ::Service { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Traits #### Trait `Connected` Trait that connected IO resources implement and use to produce information about the connection. The goal for this trait is to allow users to implement custom IO types that can still provide the same connection metadata. See [`Router::into_make_service_with_connect_info`] for more details. [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info ```rust pub trait Connected: Clone + Send + Sync + ''static { /* Associated items */ } ``` > This trait is not object-safe and cannot be used in dynamic trait objects. ##### Required Items ###### Required Methods - `connect_info`: Create type holding information about the connection. ##### Implementations This trait is implemented for the following types: - `SocketAddr` - `::Addr` with <''a, L, F> - `std::net::SocketAddr` ## Module `path` Extractor that will get captures from the URL and parse them using [`serde`]. ```rust pub mod path { /* ... */ } ``` ### Types #### Struct `Path` Extractor that will get captures from the URL and parse them using [`serde`]. Any percent encoded parameters will be automatically decoded. The decoded parameters must be valid UTF-8, otherwise `Path` will fail and return a `400 Bad Request` response. # `Option>` behavior You can use `Option>` as an extractor to allow the same handler to be used in a route with parameters that deserialize to `T`, and another route with no parameters at all. # Example These examples assume the `serde` feature of the [`uuid`] crate is enabled. One `Path` can extract multiple captures. It is not necessary (and does not work) to give a handler more than one `Path` argument. [`uuid`]: https://crates.io/crates/uuid ```rust,no_run use axum::{ extract::Path, routing::get, Router, }; use uuid::Uuid; async fn users_teams_show( Path((user_id, team_id)): Path<(Uuid, Uuid)>, ) { // ... } let app = Router::new().route("/users/{user_id}/team/{team_id}", get(users_teams_show)); # let _: Router = app; ``` If the path contains only one parameter, then you can omit the tuple. ```rust,no_run use axum::{ extract::Path, routing::get, Router, }; use uuid::Uuid; async fn user_info(Path(user_id): Path) { // ... } let app = Router::new().route("/users/{user_id}", get(user_info)); # let _: Router = app; ``` Path segments also can be deserialized into any type that implements [`serde::Deserialize`]. This includes tuples and structs: ```rust,no_run use axum::{ extract::Path, routing::get, Router, }; use serde::Deserialize; use uuid::Uuid; // Path segment labels will be matched with struct field names #[derive(Deserialize)] struct Params { user_id: Uuid, team_id: Uuid, } async fn users_teams_show( Path(Params { user_id, team_id }): Path, ) { // ... } // When using tuples the path segments will be matched by their position in the route async fn users_teams_create( Path((user_id, team_id)): Path<(String, String)>, ) { // ... } let app = Router::new().route( "/users/{user_id}/team/{team_id}", get(users_teams_show).post(users_teams_create), ); # let _: Router = app; ``` If you wish to capture all path parameters you can use `HashMap` or `Vec`: ```rust,no_run use axum::{ extract::Path, routing::get, Router, }; use std::collections::HashMap; async fn params_map( Path(params): Path>, ) { // ... } async fn params_vec( Path(params): Path>, ) { // ... } let app = Router::new() .route("/users/{user_id}/team/{team_id}", get(params_map).post(params_vec)); # let _: Router = app; ``` # Providing detailed rejection output If the URI cannot be deserialized into the target type the request will be rejected and an error response will be returned. See [`customize-path-rejection`] for an example of how to customize that error. [`serde`]: https://crates.io/crates/serde [`serde::Deserialize`]: https://docs.rs/serde/1.0.127/serde/trait.Deserialize.html [`customize-path-rejection`]: https://github.com/tokio-rs/axum/blob/main/examples/customize-path-rejection/src/main.rs ```rust pub struct Path(pub T); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `T` | | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **CryptoRng** - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Deref** - ```rust fn deref(self: &Self) -> &::Target { /* ... */ } ``` - **DerefMut** - ```rust fn deref_mut(self: &mut Self) -> &mut ::Target { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRequest** - ```rust fn from_request(req: Request, state: &S) -> impl Future>::Rejection>> { /* ... */ } ``` - **FromRequestParts** - ```rust async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result::Rejection> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **OptionalFromRequestParts** - ```rust async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result, ::Rejection> { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **Receiver** - **RefUnwindSafe** - **Rng** - **RngCore** - ```rust fn next_u32(self: &mut Self) -> u32 { /* ... */ } ``` - ```rust fn next_u64(self: &mut Self) -> u64 { /* ... */ } ``` - ```rust fn fill_bytes(self: &mut Self, dst: &mut [u8]) { /* ... */ } ``` - **Same** - **Send** - **ServiceExt** - **Sync** - **TryCryptoRng** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **TryRngCore** - ```rust fn try_next_u32(self: &mut Self) -> Result::Error> { /* ... */ } ``` - ```rust fn try_next_u64(self: &mut Self) -> Result::Error> { /* ... */ } ``` - ```rust fn try_fill_bytes(self: &mut Self, dst: &mut [u8]) -> Result<(), ::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `ErrorKind` **Attributes:** - `MustUse { reason: None }` - `NonExhaustive` The kinds of errors that can happen we deserializing into a [`Path`]. This type is obtained through [`FailedToDeserializePathParams::kind`] or [`FailedToDeserializePathParams::into_kind`] and is useful for building more precise error messages. ```rust pub enum ErrorKind { WrongNumberOfParameters { got: usize, expected: usize, }, ParseErrorAtKey { key: String, value: String, expected_type: &''static str, }, ParseErrorAtIndex { index: usize, value: String, expected_type: &''static str, }, ParseError { value: String, expected_type: &''static str, }, InvalidUtf8InPathParam { key: String, }, UnsupportedType { name: &''static str, }, DeserializeError { key: String, value: String, message: String, }, Message(String), } ``` ##### Variants ###### `WrongNumberOfParameters` The URI contained the wrong number of parameters. Fields: | Name | Type | Documentation | |------|------|---------------| | `got` | `usize` | The number of actual parameters in the URI. | | `expected` | `usize` | The number of expected parameters. | ###### `ParseErrorAtKey` Failed to parse the value at a specific key into the expected type. This variant is used when deserializing into types that have named fields, such as structs. Fields: | Name | Type | Documentation | |------|------|---------------| | `key` | `String` | The key at which the value was located. | | `value` | `String` | The value from the URI. | | `expected_type` | `&''static str` | The expected type of the value. | ###### `ParseErrorAtIndex` Failed to parse the value at a specific index into the expected type. This variant is used when deserializing into sequence types, such as tuples. Fields: | Name | Type | Documentation | |------|------|---------------| | `index` | `usize` | The index at which the value was located. | | `value` | `String` | The value from the URI. | | `expected_type` | `&''static str` | The expected type of the value. | ###### `ParseError` Failed to parse a value into the expected type. This variant is used when deserializing into a primitive type (such as `String` and `u32`). Fields: | Name | Type | Documentation | |------|------|---------------| | `value` | `String` | The value from the URI. | | `expected_type` | `&''static str` | The expected type of the value. | ###### `InvalidUtf8InPathParam` A parameter contained text that, once percent decoded, wasn't valid UTF-8. Fields: | Name | Type | Documentation | |------|------|---------------| | `key` | `String` | The key at which the invalid value was located. | ###### `UnsupportedType` Tried to serialize into an unsupported type such as nested maps. This error kind is caused by programmer errors and thus gets converted into a `500 Internal Server Error` response. Fields: | Name | Type | Documentation | |------|------|---------------| | `name` | `&''static str` | The name of the unsupported type. | ###### `DeserializeError` Failed to deserialize the value with a custom deserialization error. Fields: | Name | Type | Documentation | |------|------|---------------| | `key` | `String` | The key at which the invalid value was located. | | `value` | `String` | The value that failed to deserialize. | | `message` | `String` | The deserializaation failure message. | ###### `Message` Catch-all variant for errors that don't fit any other variant. Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `String` | | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **Eq** - **Equivalent** - ```rust fn equivalent(self: &Self, key: &K) -> bool { /* ... */ } ``` - ```rust fn equivalent(self: &Self, key: &K) -> bool { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PartialEq** - ```rust fn eq(self: &Self, other: &ErrorKind) -> bool { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **StructuralPartialEq** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `FailedToDeserializePathParams` Rejection type for [`Path`] if the captured routes params couldn't be deserialized into the expected type. ```rust pub struct FailedToDeserializePathParams(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Methods - ```rust pub fn kind(self: &Self) -> &ErrorKind { /* ... */ } ``` Get a reference to the underlying error kind. - ```rust pub fn into_kind(self: Self) -> ErrorKind { /* ... */ } ``` Convert this error into the underlying error kind. - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: FailedToDeserializePathParams) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `RawPathParams` Extractor that will get captures from the URL without deserializing them. In general you should prefer to use [`Path`] as it is higher level, however `RawPathParams` is suitable if just want the raw params without deserializing them and thus saving some allocations. Any percent encoded parameters will be automatically decoded. The decoded parameters must be valid UTF-8, otherwise `RawPathParams` will fail and return a `400 Bad Request` response. # Example ```rust,no_run use axum::{ extract::RawPathParams, routing::get, Router, }; async fn users_teams_show(params: RawPathParams) { for (key, value) in ¶ms { println!("{key:?} = {value:?}"); } } let app = Router::new().route("/users/{user_id}/team/{team_id}", get(users_teams_show)); # let _: Router = app; ``` ```rust pub struct RawPathParams(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Methods - ```rust pub fn iter(self: &Self) -> RawPathParamsIter<''_> { /* ... */ } ``` Get an iterator over the path parameters. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRequest** - ```rust fn from_request(req: Request, state: &S) -> impl Future>::Rejection>> { /* ... */ } ``` - **FromRequestParts** - ```rust async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result::Rejection> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoIterator** - ```rust fn into_iter(self: Self) -> ::IntoIter { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `RawPathParamsIter` An iterator over raw path parameters. Created with [`RawPathParams::iter`]. ```rust pub struct RawPathParamsIter<''a>(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoIterator** - ```rust fn into_iter(self: Self) -> I { /* ... */ } ``` - **Iterator** - ```rust fn next(self: &mut Self) -> Option<::Item> { /* ... */ } ``` - **IteratorRandom** - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `InvalidUtf8InPathParam` Rejection used by [`RawPathParams`] if a parameter contained text that, once percent decoded, wasn't valid UTF-8. ```rust pub struct InvalidUtf8InPathParam { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidUtf8InPathParam) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ## Module `rejection` Rejection response types. ```rust pub mod rejection { /* ... */ } ``` ### Types #### Struct `JsonDataError` **Attributes:** - `Other("#[(docsrs, doc(cfg(feature = \"json\")))]")` - `Other("#[doc(cfg(feature = \"json\"))]")` Rejection type for [`Json`](super::Json). This rejection is used if the request body is syntactically valid JSON but couldn't be deserialized into the target type. ```rust pub struct JsonDataError(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: JsonDataError) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `JsonSyntaxError` **Attributes:** - `Other("#[(docsrs, doc(cfg(feature = \"json\")))]")` - `Other("#[doc(cfg(feature = \"json\"))]")` Rejection type for [`Json`](super::Json). This rejection is used if the request body didn't contain syntactically valid JSON. ```rust pub struct JsonSyntaxError(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: JsonSyntaxError) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `MissingJsonContentType` **Attributes:** - `Other("#[(docsrs, doc(cfg(feature = \"json\")))]")` - `Other("#[doc(cfg(feature = \"json\"))]")` - `NonExhaustive` Rejection type for [`Json`](super::Json) used if the `Content-Type` header is missing. ```rust pub struct MissingJsonContentType; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: MissingJsonContentType) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `MissingExtension` Rejection type for [`Extension`](super::Extension) if an expected request extension was not found. ```rust pub struct MissingExtension(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: MissingExtension) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `MissingPathParams` **Attributes:** - `NonExhaustive` Rejection type used if axum's internal representation of path parameters is missing. This is commonly caused by extracting `Request<_>`. `Path` must be extracted first. ```rust pub struct MissingPathParams; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: MissingPathParams) -> Self { /* ... */ } ``` - ```rust fn from(inner: MissingPathParams) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `InvalidFormContentType` **Attributes:** - `NonExhaustive` Rejection type for [`Form`](super::Form) or [`RawForm`](super::RawForm) used if the `Content-Type` header is missing or its value is not `application/x-www-form-urlencoded`. ```rust pub struct InvalidFormContentType; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidFormContentType) -> Self { /* ... */ } ``` - ```rust fn from(inner: InvalidFormContentType) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `FailedToDeserializeForm` Rejection type used if the [`Form`](super::Form) extractor is unable to deserialize the form into the target type. ```rust pub struct FailedToDeserializeForm(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: FailedToDeserializeForm) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `FailedToDeserializeFormBody` Rejection type used if the [`Form`](super::Form) extractor is unable to deserialize the form body into the target type. ```rust pub struct FailedToDeserializeFormBody(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: FailedToDeserializeFormBody) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `FailedToDeserializeQueryString` Rejection type used if the [`Query`](super::Query) extractor is unable to deserialize the query string into the target type. ```rust pub struct FailedToDeserializeQueryString(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: FailedToDeserializeQueryString) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `QueryRejection` **Attributes:** - `NonExhaustive` Rejection used for [`Query`](super::Query). Contains one variant for each way the [`Query`](super::Query) extractor can fail. ```rust pub enum QueryRejection { FailedToDeserializeQueryString(FailedToDeserializeQueryString), } ``` ##### Variants ###### `FailedToDeserializeQueryString` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `FailedToDeserializeQueryString` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: FailedToDeserializeQueryString) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `FormRejection` **Attributes:** - `NonExhaustive` Rejection used for [`Form`](super::Form). Contains one variant for each way the [`Form`](super::Form) extractor can fail. ```rust pub enum FormRejection { InvalidFormContentType(InvalidFormContentType), FailedToDeserializeForm(FailedToDeserializeForm), FailedToDeserializeFormBody(FailedToDeserializeFormBody), BytesRejection(BytesRejection), } ``` ##### Variants ###### `InvalidFormContentType` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `InvalidFormContentType` | | ###### `FailedToDeserializeForm` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `FailedToDeserializeForm` | | ###### `FailedToDeserializeFormBody` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `FailedToDeserializeFormBody` | | ###### `BytesRejection` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `BytesRejection` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidFormContentType) -> Self { /* ... */ } ``` - ```rust fn from(inner: FailedToDeserializeForm) -> Self { /* ... */ } ``` - ```rust fn from(inner: FailedToDeserializeFormBody) -> Self { /* ... */ } ``` - ```rust fn from(inner: BytesRejection) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `RawFormRejection` **Attributes:** - `NonExhaustive` Rejection used for [`RawForm`](super::RawForm). Contains one variant for each way the [`RawForm`](super::RawForm) extractor can fail. ```rust pub enum RawFormRejection { InvalidFormContentType(InvalidFormContentType), BytesRejection(BytesRejection), } ``` ##### Variants ###### `InvalidFormContentType` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `InvalidFormContentType` | | ###### `BytesRejection` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `BytesRejection` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidFormContentType) -> Self { /* ... */ } ``` - ```rust fn from(inner: BytesRejection) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `JsonRejection` **Attributes:** - `Other("#[(docsrs, doc(cfg(feature = \"json\")))]")` - `Other("#[doc(cfg(feature = \"json\"))]")` - `NonExhaustive` Rejection used for [`Json`](super::Json). Contains one variant for each way the [`Json`](super::Json) extractor can fail. ```rust pub enum JsonRejection { JsonDataError(JsonDataError), JsonSyntaxError(JsonSyntaxError), MissingJsonContentType(MissingJsonContentType), BytesRejection(BytesRejection), } ``` ##### Variants ###### `JsonDataError` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `JsonDataError` | | ###### `JsonSyntaxError` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `JsonSyntaxError` | | ###### `MissingJsonContentType` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `MissingJsonContentType` | | ###### `BytesRejection` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `BytesRejection` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: JsonDataError) -> Self { /* ... */ } ``` - ```rust fn from(inner: JsonSyntaxError) -> Self { /* ... */ } ``` - ```rust fn from(inner: MissingJsonContentType) -> Self { /* ... */ } ``` - ```rust fn from(inner: BytesRejection) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `ExtensionRejection` **Attributes:** - `NonExhaustive` Rejection used for [`Extension`](super::Extension). Contains one variant for each way the [`Extension`](super::Extension) extractor can fail. ```rust pub enum ExtensionRejection { MissingExtension(MissingExtension), } ``` ##### Variants ###### `MissingExtension` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `MissingExtension` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: MissingExtension) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `PathRejection` **Attributes:** - `NonExhaustive` Rejection used for [`Path`](super::Path). Contains one variant for each way the [`Path`](super::Path) extractor can fail. ```rust pub enum PathRejection { FailedToDeserializePathParams(FailedToDeserializePathParams), MissingPathParams(MissingPathParams), } ``` ##### Variants ###### `FailedToDeserializePathParams` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `FailedToDeserializePathParams` | | ###### `MissingPathParams` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `MissingPathParams` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: FailedToDeserializePathParams) -> Self { /* ... */ } ``` - ```rust fn from(inner: MissingPathParams) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `RawPathParamsRejection` **Attributes:** - `NonExhaustive` Rejection used for [`RawPathParams`](super::RawPathParams). Contains one variant for each way the [`RawPathParams`](super::RawPathParams) extractor can fail. ```rust pub enum RawPathParamsRejection { InvalidUtf8InPathParam(InvalidUtf8InPathParam), MissingPathParams(MissingPathParams), } ``` ##### Variants ###### `InvalidUtf8InPathParam` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `InvalidUtf8InPathParam` | | ###### `MissingPathParams` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `MissingPathParams` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidUtf8InPathParam) -> Self { /* ... */ } ``` - ```rust fn from(inner: MissingPathParams) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `MatchedPathMissing` **Attributes:** - `Other("#[(docsrs, doc(cfg(feature = \"matched-path\")))]")` - `Other("#[doc(cfg(feature = \"matched-path\"))]")` - `NonExhaustive` Rejection if no matched path could be found. See [`MatchedPath`](super::MatchedPath) for more details. ```rust pub struct MatchedPathMissing; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: MatchedPathMissing) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `MatchedPathRejection` **Attributes:** - `Other("#[(docsrs, doc(cfg(feature = \"matched-path\")))]")` - `Other("#[doc(cfg(feature = \"matched-path\"))]")` - `NonExhaustive` Rejection used for [`MatchedPath`](super::MatchedPath). ```rust pub enum MatchedPathRejection { MatchedPathMissing(MatchedPathMissing), } ``` ##### Variants ###### `MatchedPathMissing` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `MatchedPathMissing` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: MatchedPathMissing) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `NestedPathRejection` **Attributes:** - `NonExhaustive` Rejection type for [`NestedPath`](super::NestedPath). This rejection is used if the matched route wasn't nested. ```rust pub struct NestedPathRejection; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Re-exports #### Re-export `FailedToDeserializePathParams` ```rust pub use crate::extract::path::FailedToDeserializePathParams; ``` #### Re-export `InvalidUtf8InPathParam` ```rust pub use crate::extract::path::InvalidUtf8InPathParam; ``` #### Re-export `axum_core::extract::rejection::*` ```rust pub use axum_core::extract::rejection::*; ``` ## Module `ws` **Attributes:** - `Other("#[(feature = \"ws\")]")` Handle WebSocket connections. # Example ``` use axum::{ extract::ws::{WebSocketUpgrade, WebSocket}, routing::any, response::{IntoResponse, Response}, Router, }; let app = Router::new().route("/ws", any(handler)); async fn handler(ws: WebSocketUpgrade) -> Response { ws.on_upgrade(handle_socket) } async fn handle_socket(mut socket: WebSocket) { while let Some(msg) = socket.recv().await { let msg = if let Ok(msg) = msg { msg } else { // client disconnected return; }; if socket.send(msg).await.is_err() { // client disconnected return; } } } # let _: Router = app; ``` # Passing data and/or state to an `on_upgrade` callback ``` use axum::{ extract::{ws::{WebSocketUpgrade, WebSocket}, State}, response::Response, routing::any, Router, }; #[derive(Clone)] struct AppState { // ... } async fn handler(ws: WebSocketUpgrade, State(state): State) -> Response { ws.on_upgrade(|socket| handle_socket(socket, state)) } async fn handle_socket(socket: WebSocket, state: AppState) { // ... } let app = Router::new() .route("/ws", any(handler)) .with_state(AppState { /* ... */ }); # let _: Router = app; ``` # Read and write concurrently If you need to read and write concurrently from a [`WebSocket`] you can use [`StreamExt::split`]: ```rust,no_run use axum::{Error, extract::ws::{WebSocket, Message}}; use futures_util::{sink::SinkExt, stream::{StreamExt, SplitSink, SplitStream}}; async fn handle_socket(mut socket: WebSocket) { let (mut sender, mut receiver) = socket.split(); tokio::spawn(write(sender)); tokio::spawn(read(receiver)); } async fn read(receiver: SplitStream) { // ... } async fn write(sender: SplitSink) { // ... } ``` [`StreamExt::split`]: https://docs.rs/futures/0.3.17/futures/stream/trait.StreamExt.html#method.split ```rust pub mod ws { /* ... */ } ``` ### Modules ## Module `rejection` WebSocket specific rejections. ```rust pub mod rejection { /* ... */ } ``` ### Types #### Struct `MethodNotGet` **Attributes:** - `NonExhaustive` Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade). ```rust pub struct MethodNotGet; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: MethodNotGet) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `MethodNotConnect` **Attributes:** - `NonExhaustive` Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade). ```rust pub struct MethodNotConnect; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: MethodNotConnect) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `InvalidConnectionHeader` **Attributes:** - `NonExhaustive` Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade). ```rust pub struct InvalidConnectionHeader; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidConnectionHeader) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `InvalidUpgradeHeader` **Attributes:** - `NonExhaustive` Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade). ```rust pub struct InvalidUpgradeHeader; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidUpgradeHeader) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `InvalidProtocolPseudoheader` **Attributes:** - `NonExhaustive` Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade). ```rust pub struct InvalidProtocolPseudoheader; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidProtocolPseudoheader) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `InvalidWebSocketVersionHeader` **Attributes:** - `NonExhaustive` Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade). ```rust pub struct InvalidWebSocketVersionHeader; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidWebSocketVersionHeader) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `WebSocketKeyHeaderMissing` **Attributes:** - `NonExhaustive` Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade). ```rust pub struct WebSocketKeyHeaderMissing; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: WebSocketKeyHeaderMissing) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `ConnectionNotUpgradable` **Attributes:** - `NonExhaustive` Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade). This rejection is returned if the connection cannot be upgraded for example if the request is HTTP/1.0. See [MDN] for more details about connection upgrades. [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade ```rust pub struct ConnectionNotUpgradable; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: ConnectionNotUpgradable) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `WebSocketUpgradeRejection` **Attributes:** - `NonExhaustive` Rejection used for [`WebSocketUpgrade`](super::WebSocketUpgrade). Contains one variant for each way the [`WebSocketUpgrade`](super::WebSocketUpgrade) extractor can fail. ```rust pub enum WebSocketUpgradeRejection { MethodNotGet(MethodNotGet), MethodNotConnect(MethodNotConnect), InvalidConnectionHeader(InvalidConnectionHeader), InvalidUpgradeHeader(InvalidUpgradeHeader), InvalidProtocolPseudoheader(InvalidProtocolPseudoheader), InvalidWebSocketVersionHeader(InvalidWebSocketVersionHeader), WebSocketKeyHeaderMissing(WebSocketKeyHeaderMissing), ConnectionNotUpgradable(ConnectionNotUpgradable), } ``` ##### Variants ###### `MethodNotGet` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `MethodNotGet` | | ###### `MethodNotConnect` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `MethodNotConnect` | | ###### `InvalidConnectionHeader` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `InvalidConnectionHeader` | | ###### `InvalidUpgradeHeader` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `InvalidUpgradeHeader` | | ###### `InvalidProtocolPseudoheader` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `InvalidProtocolPseudoheader` | | ###### `InvalidWebSocketVersionHeader` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `InvalidWebSocketVersionHeader` | | ###### `WebSocketKeyHeaderMissing` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `WebSocketKeyHeaderMissing` | | ###### `ConnectionNotUpgradable` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `ConnectionNotUpgradable` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: MethodNotGet) -> Self { /* ... */ } ``` - ```rust fn from(inner: MethodNotConnect) -> Self { /* ... */ } ``` - ```rust fn from(inner: InvalidConnectionHeader) -> Self { /* ... */ } ``` - ```rust fn from(inner: InvalidUpgradeHeader) -> Self { /* ... */ } ``` - ```rust fn from(inner: InvalidProtocolPseudoheader) -> Self { /* ... */ } ``` - ```rust fn from(inner: InvalidWebSocketVersionHeader) -> Self { /* ... */ } ``` - ```rust fn from(inner: WebSocketKeyHeaderMissing) -> Self { /* ... */ } ``` - ```rust fn from(inner: ConnectionNotUpgradable) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ## Module `close_code` Constants for [`CloseCode`]s. [`CloseCode`]: super::CloseCode ```rust pub mod close_code { /* ... */ } ``` ### Constants and Statics #### Constant `NORMAL` Indicates a normal closure, meaning that the purpose for which the connection was established has been fulfilled. ```rust pub const NORMAL: u16 = 1000; ``` #### Constant `AWAY` Indicates that an endpoint is "going away", such as a server going down or a browser having navigated away from a page. ```rust pub const AWAY: u16 = 1001; ``` #### Constant `PROTOCOL` Indicates that an endpoint is terminating the connection due to a protocol error. ```rust pub const PROTOCOL: u16 = 1002; ``` #### Constant `UNSUPPORTED` Indicates that an endpoint is terminating the connection because it has received a type of data that it cannot accept. For example, an endpoint MAY send this if it understands only text data, but receives a binary message. ```rust pub const UNSUPPORTED: u16 = 1003; ``` #### Constant `STATUS` Indicates that no status code was included in a closing frame. ```rust pub const STATUS: u16 = 1005; ``` #### Constant `ABNORMAL` Indicates an abnormal closure. ```rust pub const ABNORMAL: u16 = 1006; ``` #### Constant `INVALID` Indicates that an endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the message. For example, an endpoint received non-UTF-8 RFC3629 data within a text message. ```rust pub const INVALID: u16 = 1007; ``` #### Constant `POLICY` Indicates that an endpoint is terminating the connection because it has received a message that violates its policy. This is a generic status code that can be returned when there is no other more suitable status code (e.g., `UNSUPPORTED` or `SIZE`) or if there is a need to hide specific details about the policy. ```rust pub const POLICY: u16 = 1008; ``` #### Constant `SIZE` Indicates that an endpoint is terminating the connection because it has received a message that is too big for it to process. ```rust pub const SIZE: u16 = 1009; ``` #### Constant `EXTENSION` Indicates that an endpoint (client) is terminating the connection because the server did not respond to extension negotiation correctly. Specifically, the client has expected the server to negotiate one or more extension(s), but the server didn't return them in the response message of the WebSocket handshake. The list of extensions that are needed should be given as the reason for closing. Note that this status code is not used by the server, because it can fail the WebSocket handshake instead. ```rust pub const EXTENSION: u16 = 1010; ``` #### Constant `ERROR` Indicates that a server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request. ```rust pub const ERROR: u16 = 1011; ``` #### Constant `RESTART` Indicates that the server is restarting. ```rust pub const RESTART: u16 = 1012; ``` #### Constant `AGAIN` Indicates that the server is overloaded and the client should either connect to a different IP (when multiple targets exist), or reconnect to the same IP when a user has performed an action. ```rust pub const AGAIN: u16 = 1013; ``` ### Types #### Struct `WebSocketUpgrade` **Attributes:** - `Other("#[(docsrs, doc(cfg(feature = \"ws\")))]")` - `Other("#[doc(cfg(feature = \"ws\"))]")` - `MustUse { reason: None }` Extractor for establishing WebSocket connections. For HTTP/1.1 requests, this extractor requires the request method to be `GET`; in later versions, `CONNECT` is used instead. To support both, it should be used with [`any`](crate::routing::any). See the [module docs](self) for an example. [`MethodFilter`]: crate::routing::MethodFilter ```rust pub struct WebSocketUpgrade { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn read_buffer_size(self: Self, size: usize) -> Self { /* ... */ } ``` Read buffer capacity. The default value is 128KiB - ```rust pub fn write_buffer_size(self: Self, size: usize) -> Self { /* ... */ } ``` The target minimum size of the write buffer to reach before writing the data - ```rust pub fn max_write_buffer_size(self: Self, max: usize) -> Self { /* ... */ } ``` The max size of the write buffer in bytes. Setting this can provide backpressure - ```rust pub fn max_message_size(self: Self, max: usize) -> Self { /* ... */ } ``` Set the maximum message size (defaults to 64 megabytes) - ```rust pub fn max_frame_size(self: Self, max: usize) -> Self { /* ... */ } ``` Set the maximum frame size (defaults to 16 megabytes) - ```rust pub fn accept_unmasked_frames(self: Self, accept: bool) -> Self { /* ... */ } ``` Allow server to accept unmasked frames (defaults to false) - ```rust pub fn protocols(self: Self, protocols: I) -> Self where I: IntoIterator, ::Item: Into> { /* ... */ } ``` Set the known protocols. - ```rust pub fn selected_protocol(self: &Self) -> Option<&HeaderValue> { /* ... */ } ``` Return the selected WebSocket subprotocol, if one has been chosen. - ```rust pub fn on_failed_upgrade(self: Self, callback: C) -> WebSocketUpgrade where C: OnFailedUpgrade { /* ... */ } ``` Provide a callback to call if upgrading the connection fails. - ```rust pub fn on_upgrade(self: Self, callback: C) -> Response where C: FnOnce(WebSocket) -> Fut + Send + ''static, Fut: Future + Send + ''static, F: OnFailedUpgrade { /* ... */ } ``` Finalize upgrading the connection and call the provided callback with ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRequest** - ```rust fn from_request(req: Request, state: &S) -> impl Future>::Rejection>> { /* ... */ } ``` - **FromRequestParts** - ```rust async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result::Rejection> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `DefaultOnFailedUpgrade` **Attributes:** - `NonExhaustive` The default `OnFailedUpgrade` used by `WebSocketUpgrade`. It simply ignores the error. ```rust pub struct DefaultOnFailedUpgrade; ``` ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **OnFailedUpgrade** - ```rust fn call(self: Self, _error: Error) { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `WebSocket` A stream of WebSocket messages. See [the module level documentation](self) for more details. ```rust pub struct WebSocket { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub async fn recv(self: &mut Self) -> Option> { /* ... */ } ``` Receive another message. - ```rust pub async fn send(self: &mut Self, msg: Message) -> Result<(), Error> { /* ... */ } ``` Send a message. - ```rust pub fn protocol(self: &Self) -> Option<&HeaderValue> { /* ... */ } ``` Return the selected WebSocket subprotocol, if one has been chosen. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FusedStream** - ```rust fn is_terminated(self: &Self) -> bool { /* ... */ } ``` Returns true if the websocket has been terminated. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sink** - ```rust fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn start_send(self: Pin<&mut Self>, item: Message) -> Result<(), ::Error> { /* ... */ } ``` - ```rust fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn poll_close(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - **SinkExt** - **Stream** - ```rust fn poll_next(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll::Item>> { /* ... */ } ``` - **StreamExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **TryStream** - ```rust fn try_poll_next(self: Pin<&mut S>, cx: &mut Context<''_>) -> Poll::Ok, ::Error>>> { /* ... */ } ``` - **TryStreamExt** - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `Utf8Bytes` UTF-8 wrapper for [Bytes]. An [Utf8Bytes] is always guaranteed to contain valid UTF-8. ```rust pub struct Utf8Bytes(/* private field */); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `private` | *Private field* | ##### Implementations ###### Methods - ```rust pub const fn from_static(str: &''static str) -> Self { /* ... */ } ``` Creates from a static str. - ```rust pub fn as_str(self: &Self) -> &str { /* ... */ } ``` Returns as a string slice. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Utf8Bytes { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Utf8Bytes { /* ... */ } ``` - **Deref** - ```rust fn deref(self: &Self) -> &::Target { /* ... */ } ``` ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **Eq** - **Equivalent** - ```rust fn equivalent(self: &Self, key: &K) -> bool { /* ... */ } ``` - ```rust fn equivalent(self: &Self, key: &K) -> bool { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(s: String) -> Self { /* ... */ } ``` - ```rust fn from(s: &str) -> Self { /* ... */ } ``` - ```rust fn from(s: &String) -> Self { /* ... */ } ``` - ```rust fn from(Utf8Bytes: Utf8Bytes) -> Self { /* ... */ } ``` - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PartialEq** - ```rust fn eq(self: &Self, other: &Utf8Bytes) -> bool { /* ... */ } ``` - ```rust fn eq(self: &Self, other: &T) -> bool { /* ... */ } ``` ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **Receiver** - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **StructuralPartialEq** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - ```rust fn try_from(bytes: Bytes) -> Result::Error> { /* ... */ } ``` - ```rust fn try_from(v: Vec) -> Result::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Type Alias `CloseCode` Status code used to indicate why an endpoint is closing the WebSocket connection. ```rust pub type CloseCode = u16; ``` #### Struct `CloseFrame` A struct representing the close command. ```rust pub struct CloseFrame { pub code: CloseCode, pub reason: Utf8Bytes, } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | `code` | `CloseCode` | The reason as a code. | | `reason` | `Utf8Bytes` | The reason as text string. | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> CloseFrame { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Eq** - **Equivalent** - ```rust fn equivalent(self: &Self, key: &K) -> bool { /* ... */ } ``` - ```rust fn equivalent(self: &Self, key: &K) -> bool { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PartialEq** - ```rust fn eq(self: &Self, other: &CloseFrame) -> bool { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **StructuralPartialEq** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `Message` A WebSocket message. ```rust pub enum Message { Text(Utf8Bytes), Binary(crate::body::Bytes), Ping(crate::body::Bytes), Pong(crate::body::Bytes), Close(Option), } ``` ##### Variants ###### `Text` A text WebSocket message Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `Utf8Bytes` | | ###### `Binary` A binary WebSocket message Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `crate::body::Bytes` | | ###### `Ping` A ping message with the specified payload The payload here must have a length less than 125 bytes. Ping messages will be automatically responded to by the server, so you do not have to worry about dealing with them yourself. Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `crate::body::Bytes` | | ###### `Pong` A pong message with the specified payload The payload here must have a length less than 125 bytes. Pong messages will be automatically sent to the client if a ping message is received, so you do not have to worry about constructing them yourself unless you want to implement a [unidirectional heartbeat](https://tools.ietf.org/html/rfc6455#section-5.5.3). Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `crate::body::Bytes` | | ###### `Close` A close message with the optional close frame. You may "uncleanly" close a WebSocket connection at any time by simply dropping the [`WebSocket`]. However, you may also use the graceful closing protocol, in which 1. peer A sends a close frame, and does not send any further messages; 2. peer B responds with a close frame, and does not send any further messages; 3. peer A processes the remaining messages sent by peer B, before finally 4. both peers close the connection. After sending a close frame, you may still read messages, but attempts to send another message will error. After receiving a close frame, axum will automatically respond with a close frame if necessary (you do not have to deal with this yourself). Since no further messages will be received, you may either do nothing or explicitly drop the connection. Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `Option` | | ##### Implementations ###### Methods - ```rust pub fn into_data(self: Self) -> Bytes { /* ... */ } ``` Consume the WebSocket and return it as binary data. - ```rust pub fn into_text(self: Self) -> Result { /* ... */ } ``` Attempt to consume the WebSocket message and convert it to a Utf8Bytes. - ```rust pub fn to_text(self: &Self) -> Result<&str, Error> { /* ... */ } ``` Attempt to get a &str from the WebSocket message, - ```rust pub fn text(string: S) -> Message where S: Into { /* ... */ } ``` Create a new text WebSocket message from a stringable. - ```rust pub fn binary(bin: B) -> Message where B: Into { /* ... */ } ``` Create a new binary WebSocket message by converting to `Bytes`. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Message { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Eq** - **Equivalent** - ```rust fn equivalent(self: &Self, key: &K) -> bool { /* ... */ } ``` - ```rust fn equivalent(self: &Self, key: &K) -> bool { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(string: String) -> Self { /* ... */ } ``` - ```rust fn from(string: &''s str) -> Self { /* ... */ } ``` - ```rust fn from(data: &''b [u8]) -> Self { /* ... */ } ``` - ```rust fn from(data: Bytes) -> Self { /* ... */ } ``` - ```rust fn from(data: Vec) -> Self { /* ... */ } ``` - ```rust fn from(msg: Message) -> Self { /* ... */ } ``` - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PartialEq** - ```rust fn eq(self: &Self, other: &Message) -> bool { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sink** - ```rust fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn start_send(self: Pin<&mut Self>, item: Message) -> Result<(), ::Error> { /* ... */ } ``` - ```rust fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn poll_close(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - **StructuralPartialEq** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Traits #### Trait `OnFailedUpgrade` What to do when a connection upgrade fails. See [`WebSocketUpgrade::on_failed_upgrade`] for more details. ```rust pub trait OnFailedUpgrade: Send + ''static { /* Associated items */ } ``` ##### Required Items ###### Required Methods - `call`: Call the callback. ##### Implementations This trait is implemented for the following types: - `F` with - `DefaultOnFailedUpgrade` ## Module `multipart` **Attributes:** - `Other("#[(feature = \"multipart\")]")` Extractor that parses `multipart/form-data` requests commonly used with file uploads. See [`Multipart`] for more details. ```rust pub mod multipart { /* ... */ } ``` ### Types #### Struct `Multipart` **Attributes:** - `Other("#[(docsrs, doc(cfg(feature = \"multipart\")))]")` - `Other("#[doc(cfg(feature = \"multipart\"))]")` Extractor that parses `multipart/form-data` requests (commonly used with file uploads). ⚠️ Since extracting multipart form data from the request requires consuming the body, the `Multipart` extractor must be *last* if there are multiple extractors in a handler. See ["the order of extractors"][order-of-extractors] [order-of-extractors]: crate::extract#the-order-of-extractors # Example ```rust,no_run use axum::{ extract::Multipart, routing::post, Router, }; use futures_util::stream::StreamExt; async fn upload(mut multipart: Multipart) { while let Some(mut field) = multipart.next_field().await.unwrap() { let name = field.name().unwrap().to_string(); let data = field.bytes().await.unwrap(); println!("Length of `{}` is {} bytes", name, data.len()); } } let app = Router::new().route("/upload", post(upload)); # let _: Router = app; ``` # Large Files For security reasons, by default, `Multipart` limits the request body size to 2MB. See [`DefaultBodyLimit`][default-body-limit] for how to configure this limit. [default-body-limit]: crate::extract::DefaultBodyLimit ```rust pub struct Multipart { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub async fn next_field(self: &mut Self) -> Result>, MultipartError> { /* ... */ } ``` Yields the next [`Field`] if available. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRequest** - ```rust async fn from_request(req: Request, _state: &S) -> Result::Rejection> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **OptionalFromRequest** - ```rust async fn from_request(req: Request, _state: &S) -> Result, ::Rejection> { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `Field` A single field in a multipart stream. ```rust pub struct Field<''a> { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn name(self: &Self) -> Option<&str> { /* ... */ } ``` The field name found in the - ```rust pub fn file_name(self: &Self) -> Option<&str> { /* ... */ } ``` The file name found in the - ```rust pub fn content_type(self: &Self) -> Option<&str> { /* ... */ } ``` Get the [content type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) of the field. - ```rust pub fn headers(self: &Self) -> &HeaderMap { /* ... */ } ``` Get a map of headers as [`HeaderMap`]. - ```rust pub async fn bytes(self: Self) -> Result { /* ... */ } ``` Get the full data of the field as [`Bytes`]. - ```rust pub async fn text(self: Self) -> Result { /* ... */ } ``` Get the full field data as text. - ```rust pub async fn chunk(self: &mut Self) -> Result, MultipartError> { /* ... */ } ``` Stream a chunk of the field data. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Stream** - ```rust fn poll_next(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll::Item>> { /* ... */ } ``` - **StreamExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **TryStream** - ```rust fn try_poll_next(self: Pin<&mut S>, cx: &mut Context<''_>) -> Poll::Ok, ::Error>>> { /* ... */ } ``` - **TryStreamExt** - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `MultipartError` Errors associated with parsing `multipart/form-data` requests. ```rust pub struct MultipartError { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Enum `MultipartRejection` **Attributes:** - `NonExhaustive` Rejection used for [`Multipart`]. Contains one variant for each way the [`Multipart`] extractor can fail. ```rust pub enum MultipartRejection { InvalidBoundary(InvalidBoundary), } ``` ##### Variants ###### `InvalidBoundary` Fields: | Index | Type | Documentation | |-------|------|---------------| | 0 | `InvalidBoundary` | | ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - ```rust fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ } ``` - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidBoundary) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `InvalidBoundary` **Attributes:** - `NonExhaustive` Rejection type used if the `boundary` in a `multipart/form-data` is missing or invalid. ```rust pub struct InvalidBoundary; ``` ##### Implementations ###### Methods - ```rust pub fn body_text(self: &Self) -> String { /* ... */ } ``` Get the response body text used for this rejection. - ```rust pub fn status(self: &Self) -> http::StatusCode { /* ... */ } ``` Get the status code used for this rejection. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **Display** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Error** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(inner: InvalidBoundary) -> Self { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> $crate::response::Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToString** - ```rust fn to_string(self: &Self) -> String { /* ... */ } ``` - **ToStringFallible** - ```rust fn try_to_string(self: &Self) -> Result { /* ... */ } ``` [`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM. - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Re-exports #### Re-export `DefaultBodyLimit` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::extract::DefaultBodyLimit; ``` #### Re-export `FromRef` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::extract::FromRef; ``` #### Re-export `FromRequest` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::extract::FromRequest; ``` #### Re-export `FromRequestParts` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::extract::FromRequestParts; ``` #### Re-export `OptionalFromRequest` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::extract::OptionalFromRequest; ``` #### Re-export `OptionalFromRequestParts` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::extract::OptionalFromRequestParts; ``` #### Re-export `Request` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::extract::Request; ``` #### Re-export `FromRef` **Attributes:** - `Other("#[(feature = \"macros\")]")` ```rust pub use axum_macros::FromRef; ``` #### Re-export `FromRequest` **Attributes:** - `Other("#[(feature = \"macros\")]")` ```rust pub use axum_macros::FromRequest; ``` #### Re-export `FromRequestParts` **Attributes:** - `Other("#[(feature = \"macros\")]")` ```rust pub use axum_macros::FromRequestParts; ``` #### Re-export `NestedPath` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use self::nested_path::NestedPath; ``` #### Re-export `Path` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use self::path::Path; ``` #### Re-export `RawPathParams` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use self::path::RawPathParams; ``` #### Re-export `RawForm` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use self::raw_form::RawForm; ``` #### Re-export `RawQuery` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use self::raw_query::RawQuery; ``` #### Re-export `State` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use self::state::State; ``` #### Re-export `ConnectInfo` **Attributes:** - `Other("#[doc(inline)]")` - `Other("#[(feature = \"tokio\")]")` ```rust pub use self::connect_info::ConnectInfo; ``` #### Re-export `Json` **Attributes:** - `Other("#[doc(no_inline)]")` - `Other("#[(feature = \"json\")]")` ```rust pub use crate::Json; ``` #### Re-export `Extension` **Attributes:** - `Other("#[doc(no_inline)]")` ```rust pub use crate::Extension; ``` #### Re-export `Form` **Attributes:** - `Other("#[(feature = \"form\")]")` - `Other("#[doc(no_inline)]")` ```rust pub use crate::form::Form; ``` #### Re-export `MatchedPath` **Attributes:** - `Other("#[(feature = \"matched-path\")]")` - `Other("#[doc(inline)]")` ```rust pub use self::matched_path::MatchedPath; ``` #### Re-export `Multipart` **Attributes:** - `Other("#[(feature = \"multipart\")]")` - `Other("#[doc(inline)]")` ```rust pub use self::multipart::Multipart; ``` #### Re-export `Query` **Attributes:** - `Other("#[(feature = \"query\")]")` - `Other("#[doc(inline)]")` ```rust pub use self::query::Query; ``` #### Re-export `OriginalUri` **Attributes:** - `Other("#[(feature = \"original-uri\")]")` - `Other("#[doc(inline)]")` ```rust pub use self::original_uri::OriginalUri; ``` #### Re-export `WebSocketUpgrade` **Attributes:** - `Other("#[(feature = \"ws\")]")` - `Other("#[doc(inline)]")` ```rust pub use self::ws::WebSocketUpgrade; ``` ## Module `handler` Async functions that can be used to handle requests. In axum a "handler" is an async function that accepts zero or more ["extractors"](crate::extract) as arguments and returns something that can be converted [into a response](crate::response). Handlers are where your application logic lives and axum applications are built by routing between handlers. [`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html Some examples of handlers: ```rust use axum::{body::Bytes, http::StatusCode}; // Handler that immediately returns an empty `200 OK` response. async fn unit_handler() {} // Handler that immediately returns a `200 OK` response with a plain text // body. async fn string_handler() -> String { "Hello, World!".to_string() } // Handler that buffers the request body and returns it. // // This works because `Bytes` implements `FromRequest` // and therefore can be used as an extractor. // // `String` and `StatusCode` both implement `IntoResponse` and // therefore `Result` also implements `IntoResponse` async fn echo(body: Bytes) -> Result { if let Ok(string) = String::from_utf8(body.to_vec()) { Ok(string) } else { Err(StatusCode::BAD_REQUEST) } } ``` Instead of a direct `StatusCode`, it makes sense to use intermediate error type that can ultimately be converted to `Response`. This allows using `?` operator in handlers. See those examples: * [`anyhow-error-response`][anyhow] for generic boxed errors * [`error-handling`][error-handling] for application-specific detailed errors [anyhow]: https://github.com/tokio-rs/axum/blob/main/examples/anyhow-error-response/src/main.rs [error-handling]: https://github.com/tokio-rs/axum/blob/main/examples/error-handling/src/main.rs ## Debugging handler type errors For a function to be used as a handler it must implement the [`Handler`] trait. axum provides blanket implementations for functions that: - Are `async fn`s. - Take no more than 16 arguments that all implement `Send`. - All except the last argument implement [`FromRequestParts`]. - The last argument implements [`FromRequest`]. - Returns something that implements [`IntoResponse`]. - If a closure is used it must implement `Clone + Send` and be `'static`. - Returns a future that is `Send`. The most common way to accidentally make a future `!Send` is to hold a `!Send` type across an await. Unfortunately Rust gives poor error messages if you try to use a function that doesn't quite match what's required by [`Handler`]. You might get an error like this: ```not_rust error[E0277]: the trait bound `fn(bool) -> impl Future {handler}: Handler<_, _>` is not satisfied --> src/main.rs:13:44 | 13 | let app = Router::new().route("/", get(handler)); | ^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(bool) -> impl Future {handler}` | ::: axum/src/handler/mod.rs:116:8 | 116 | H: Handler, | ------------- required by this bound in `axum::routing::get` ``` This error doesn't tell you _why_ your function doesn't implement [`Handler`]. It's possible to improve the error with the [`debug_handler`] proc-macro from the [axum-macros] crate. [axum-macros]: https://docs.rs/axum-macros [`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html ```rust pub mod handler { /* ... */ } ``` ### Modules ## Module `future` Handler future types. ```rust pub mod future { /* ... */ } ``` ### Types #### Struct `IntoServiceFuture` The response future for [`IntoService`](super::IntoService). ```rust pub struct IntoServiceFuture { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Future** - ```rust fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<''_>) -> std::task::Poll<::Output> { /* ... */ } ``` - **FutureExt** - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoFuture** - ```rust fn into_future(self: Self) -> ::IntoFuture { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryFuture** - ```rust fn try_poll(self: Pin<&mut F>, cx: &mut Context<''_>) -> Poll<::Output> { /* ... */ } ``` - **TryFutureExt** - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `LayeredFuture` The response future for [`Layered`](super::Layered). ```rust pub struct LayeredFuture { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Future** - ```rust fn poll(self: Pin<&mut Self>, cx: &mut Context<''_>) -> std::task::Poll<::Output> { /* ... */ } ``` - **FutureExt** - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoFuture** - ```rust fn into_future(self: Self) -> ::IntoFuture { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Types #### Struct `Layered` A [`Service`] created from a [`Handler`] by applying a Tower middleware. Created with [`Handler::layer`]. See that method for more details. ```rust pub struct Layered { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Self { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Handler** - ```rust fn call(self: Self, req: Request, state: S) -> ::Future { /* ... */ } ``` - **HandlerWithoutStateExt** - ```rust fn into_service(self: Self) -> HandlerService { /* ... */ } ``` - ```rust fn into_make_service(self: Self) -> IntoMakeService> { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo, C> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Traits #### Trait `Handler` **Attributes:** - `Other("#[diagnostic::on_unimplemented(note =\n\"Consider using `#[axum::debug_handler]` to improve the error message\")]")` Trait for async functions that can be used to handle requests. You shouldn't need to depend on this trait directly. It is automatically implemented to closures of the right types. See the [module docs](crate::handler) for more details. # Converting `Handler`s into [`Service`]s To convert `Handler`s into [`Service`]s you have to call either [`HandlerWithoutStateExt::into_service`] or [`Handler::with_state`]: ``` use tower::Service; use axum::{ extract::{State, Request}, body::Body, handler::{HandlerWithoutStateExt, Handler}, }; // this handler doesn't require any state async fn one() {} // so it can be converted to a service with `HandlerWithoutStateExt::into_service` assert_service(one.into_service()); // this handler requires state async fn two(_: State) {} // so we have to provide it let handler_with_state = two.with_state(String::new()); // which gives us a `Service` assert_service(handler_with_state); // helper to check that a value implements `Service` fn assert_service(service: S) where S: Service, {} ``` ## Debugging handler type errors For a function to be used as a handler it must implement the [`Handler`] trait. axum provides blanket implementations for functions that: - Are `async fn`s. - Take no more than 16 arguments that all implement `Send`. - All except the last argument implement [`FromRequestParts`]. - The last argument implements [`FromRequest`]. - Returns something that implements [`IntoResponse`]. - If a closure is used it must implement `Clone + Send` and be `'static`. - Returns a future that is `Send`. The most common way to accidentally make a future `!Send` is to hold a `!Send` type across an await. Unfortunately Rust gives poor error messages if you try to use a function that doesn't quite match what's required by [`Handler`]. You might get an error like this: ```not_rust error[E0277]: the trait bound `fn(bool) -> impl Future {handler}: Handler<_, _>` is not satisfied --> src/main.rs:13:44 | 13 | let app = Router::new().route("/", get(handler)); | ^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(bool) -> impl Future {handler}` | ::: axum/src/handler/mod.rs:116:8 | 116 | H: Handler, | ------------- required by this bound in `axum::routing::get` ``` This error doesn't tell you _why_ your function doesn't implement [`Handler`]. It's possible to improve the error with the [`debug_handler`] proc-macro from the [axum-macros] crate. [axum-macros]: https://docs.rs/axum-macros [`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html # Handlers that aren't functions The `Handler` trait is also implemented for `T: IntoResponse`. That allows easily returning fixed data for routes: ``` use axum::{ Router, routing::{get, post}, Json, http::StatusCode, }; use serde_json::json; let app = Router::new() // respond with a fixed string .route("/", get("Hello, World!")) // or return some mock data .route("/users", post(( StatusCode::CREATED, Json(json!({ "id": 1, "username": "alice" })), ))); # let _: Router = app; ``` # About type parameter `T` **Generally you shouldn't need to worry about `T`**; when calling methods such as [`post`](crate::routing::method_routing::post) it will be automatically inferred and this is the intended way for this parameter to be provided in application code. If you are implementing your own methods that accept implementations of `Handler` as arguments, then the following may be useful: The type parameter `T` is a workaround for trait coherence rules, allowing us to write blanket implementations of `Handler` over many types of handler functions with different numbers of arguments, without the compiler forbidding us from doing so because one type `F` can in theory implement both `Fn(A) -> X` and `Fn(A, B) -> Y`. `T` is a placeholder taking on a representation of the parameters of the handler function, as well as other similar 'coherence rule workaround' discriminators, allowing us to select one function signature to use as a `Handler`. ```rust pub trait Handler: Clone + Send + Sync + Sized + ''static { /* Associated items */ } ``` > This trait is not object-safe and cannot be used in dynamic trait objects. ##### Required Items ###### Associated Types - `Future`: The type of future calling this handler returns. ###### Required Methods - `call`: Call the handler with the given request. ##### Provided Methods - ```rust fn layer(self: Self, layer: L) -> Layered where L: Layer> + Clone, ::Service: Service { /* ... */ } ``` Apply a [`tower::Layer`] to the handler. - ```rust fn with_state(self: Self, state: S) -> HandlerService { /* ... */ } ``` Convert the handler into a [`Service`] by providing the state ##### Implementations This trait is implemented for the following types: - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `F` with - `Layered` with - `MethodRouter` with #### Trait `HandlerWithoutStateExt` Extension trait for [`Handler`]s that don't have state. This provides convenience methods to convert the [`Handler`] into a [`Service`] or [`MakeService`]. [`MakeService`]: tower::make::MakeService ```rust pub trait HandlerWithoutStateExt: Handler { /* Associated items */ } ``` > This trait is not object-safe and cannot be used in dynamic trait objects. ##### Required Items ###### Required Methods - `into_service`: Convert the handler into a [`Service`] and no state. - `into_make_service`: Convert the handler into a [`MakeService`] and no state. - `into_make_service_with_connect_info`: Convert the handler into a [`MakeService`] which stores information ##### Implementations This trait is implemented for the following types: - `H` with ### Re-exports #### Re-export `HandlerService` ```rust pub use self::service::HandlerService; ``` ## Module `middleware` Utilities for writing middleware # Intro axum is unique in that it doesn't have its own bespoke middleware system and instead integrates with [`tower`]. This means the ecosystem of [`tower`] and [`tower-http`] middleware all work with axum. While it's not necessary to fully understand tower to write or use middleware with axum, having at least a basic understanding of tower's concepts is recommended. See [tower's guides][tower-guides] for a general introduction. Reading the documentation for [`tower::ServiceBuilder`] is also recommended. # Applying middleware axum allows you to add middleware just about anywhere - To entire routers with [`Router::layer`] and [`Router::route_layer`]. - To method routers with [`MethodRouter::layer`] and [`MethodRouter::route_layer`]. - To individual handlers with [`Handler::layer`]. ## Applying multiple middleware It's recommended to use [`tower::ServiceBuilder`] to apply multiple middleware at once, instead of calling `layer` (or `route_layer`) repeatedly: ```rust use axum::{ routing::get, Extension, Router, }; use tower_http::{trace::TraceLayer}; use tower::ServiceBuilder; async fn handler() {} #[derive(Clone)] struct State {} let app = Router::new() .route("/", get(handler)) .layer( ServiceBuilder::new() .layer(TraceLayer::new_for_http()) .layer(Extension(State {})) ); # let _: Router = app; ``` # Commonly used middleware Some commonly used middleware are: - [`TraceLayer`](tower_http::trace) for high level tracing/logging. - [`CorsLayer`](tower_http::cors) for handling CORS. - [`CompressionLayer`](tower_http::compression) for automatic compression of responses. - [`RequestIdLayer`](tower_http::request_id) and [`PropagateRequestIdLayer`](tower_http::request_id) set and propagate request ids. - [`TimeoutLayer`](tower_http::timeout::TimeoutLayer) for timeouts. # Ordering When you add middleware with [`Router::layer`] (or similar) all previously added routes will be wrapped in the middleware. Generally speaking, this results in middleware being executed from bottom to top. So if you do this: ```rust use axum::{routing::get, Router}; async fn handler() {} # let layer_one = axum::Extension(()); # let layer_two = axum::Extension(()); # let layer_three = axum::Extension(()); # let app = Router::new() .route("/", get(handler)) .layer(layer_one) .layer(layer_two) .layer(layer_three); # let _: Router = app; ``` Think of the middleware as being layered like an onion where each new layer wraps all previous layers: ```not_rust requests | v +----- layer_three -----+ | +---- layer_two ----+ | | | +-- layer_one --+ | | | | | | | | | | | handler | | | | | | | | | | | +-- layer_one --+ | | | +---- layer_two ----+ | +----- layer_three -----+ | v responses ``` That is: - First `layer_three` receives the request - It then does its thing and passes the request onto `layer_two` - Which passes the request onto `layer_one` - Which passes the request onto `handler` where a response is produced - That response is then passed to `layer_one` - Then to `layer_two` - And finally to `layer_three` where it's returned out of your app It's a little more complicated in practice because any middleware is free to return early and not call the next layer, for example if a request cannot be authorized, but it's a useful mental model to have. As previously mentioned it's recommended to add multiple middleware using `tower::ServiceBuilder`, however this impacts ordering: ```rust use tower::ServiceBuilder; use axum::{routing::get, Router}; async fn handler() {} # let layer_one = axum::Extension(()); # let layer_two = axum::Extension(()); # let layer_three = axum::Extension(()); # let app = Router::new() .route("/", get(handler)) .layer( ServiceBuilder::new() .layer(layer_one) .layer(layer_two) .layer(layer_three), ); # let _: Router = app; ``` `ServiceBuilder` works by composing all layers into one such that they run top to bottom. So with the previous code `layer_one` would receive the request first, then `layer_two`, then `layer_three`, then `handler`, and then the response would bubble back up through `layer_three`, then `layer_two`, and finally `layer_one`. Executing middleware top to bottom is generally easier to understand and follow mentally which is one of the reasons `ServiceBuilder` is recommended. # Writing middleware axum offers many ways of writing middleware, at different levels of abstraction and with different pros and cons. ## `axum::middleware::from_fn` Use [`axum::middleware::from_fn`] to write your middleware when: - You're not comfortable with implementing your own futures and would rather use the familiar `async`/`await` syntax. - You don't intend to publish your middleware as a crate for others to use. Middleware written like this are only compatible with axum. ## `axum::middleware::from_extractor` Use [`axum::middleware::from_extractor`] to write your middleware when: - You have a type that you sometimes want to use as an extractor and sometimes as a middleware. If you only need your type as a middleware prefer [`middleware::from_fn`]. ## tower's combinators tower has several utility combinators that can be used to perform simple modifications to requests or responses. The most commonly used ones are - [`ServiceBuilder::map_request`] - [`ServiceBuilder::map_response`] - [`ServiceBuilder::then`] - [`ServiceBuilder::and_then`] You should use these when - You want to perform a small ad hoc operation, such as adding a header. - You don't intend to publish your middleware as a crate for others to use. ## `tower::Service` and `Pin>` For maximum control (and a more low level API) you can write your own middleware by implementing [`tower::Service`]: Use [`tower::Service`] with `Pin>` to write your middleware when: - Your middleware needs to be configurable for example via builder methods on your [`tower::Layer`] such as [`tower_http::trace::TraceLayer`]. - You do intend to publish your middleware as a crate for others to use. - You're not comfortable with implementing your own futures. A decent template for such a middleware could be: ```rust use axum::{ response::Response, body::Body, extract::Request, }; use futures_util::future::BoxFuture; use tower::{Service, Layer}; use std::task::{Context, Poll}; #[derive(Clone)] struct MyLayer; impl Layer for MyLayer { type Service = MyMiddleware; fn layer(&self, inner: S) -> Self::Service { MyMiddleware { inner } } } #[derive(Clone)] struct MyMiddleware { inner: S, } impl Service for MyMiddleware where S: Service + Send + 'static, S::Future: Send + 'static, { type Response = S::Response; type Error = S::Error; // `BoxFuture` is a type alias for `Pin>` type Future = BoxFuture<'static, Result>; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.poll_ready(cx) } fn call(&mut self, request: Request) -> Self::Future { let future = self.inner.call(request); Box::pin(async move { let response: Response = future.await?; Ok(response) }) } } ``` Note that your error type being defined as `S::Error` means that your middleware typically _returns no errors_. As a principle always try to return a response and try not to bail out with a custom error type. For example, if a 3rd party library you are using inside your new middleware returns its own specialized error type, try to convert it to some reasonable response and return `Ok` with that response. If you choose to implement a custom error type such as `type Error = BoxError` (a boxed opaque error), or any other error type that is not `Infallible`, you must use a `HandleErrorLayer`, here is an example using a `ServiceBuilder`: ```ignore ServiceBuilder::new() .layer(HandleErrorLayer::new(|_: BoxError| async { // because axum uses infallible errors, you must handle your custom error type from your middleware here StatusCode::BAD_REQUEST })) .layer( // ); ``` ## `tower::Service` and custom futures If you're comfortable implementing your own futures (or want to learn it) and need as much control as possible then using `tower::Service` without boxed futures is the way to go. Use [`tower::Service`] with manual futures to write your middleware when: - You want your middleware to have the lowest possible overhead. - Your middleware needs to be configurable for example via builder methods on your [`tower::Layer`] such as [`tower_http::trace::TraceLayer`]. - You do intend to publish your middleware as a crate for others to use, perhaps as part of tower-http. - You're comfortable with implementing your own futures, or want to learn how the lower levels of async Rust works. tower's ["Building a middleware from scratch"][tower-from-scratch-guide] guide is a good place to learn how to do this. # Error handling for middleware axum's error handling model requires handlers to always return a response. However middleware is one possible way to introduce errors into an application. If hyper receives an error the connection will be closed without sending a response. Thus axum requires those errors to be handled gracefully: ```rust use axum::{ routing::get, error_handling::HandleErrorLayer, http::StatusCode, BoxError, Router, }; use tower::{ServiceBuilder, timeout::TimeoutLayer}; use std::time::Duration; async fn handler() {} let app = Router::new() .route("/", get(handler)) .layer( ServiceBuilder::new() // this middleware goes above `TimeoutLayer` because it will receive // errors returned by `TimeoutLayer` .layer(HandleErrorLayer::new(|_: BoxError| async { StatusCode::REQUEST_TIMEOUT })) .layer(TimeoutLayer::new(Duration::from_secs(10))) ); # let _: Router = app; ``` See [`error_handling`](crate::error_handling) for more details on axum's error handling model. # Routing to services/middleware and backpressure Generally routing to one of multiple services and backpressure doesn't mix well. Ideally you would want ensure a service is ready to receive a request before calling it. However, in order to know which service to call, you need the request... One approach is to not consider the router service itself ready until all destination services are ready. That is the approach used by [`tower::steer::Steer`]. Another approach is to always consider all services ready (always return `Poll::Ready(Ok(()))`) from `Service::poll_ready` and then actually drive readiness inside the response future returned by `Service::call`. This works well when your services don't care about backpressure and are always ready anyway. axum expects that all services used in your app won't care about backpressure and so it uses the latter strategy. However that means you should avoid routing to a service (or using a middleware) that _does_ care about backpressure. At the very least you should [load shed][tower::load_shed] so requests are dropped quickly and don't keep piling up. It also means that if `poll_ready` returns an error then that error will be returned in the response future from `call` and _not_ from `poll_ready`. In that case, the underlying service will _not_ be discarded and will continue to be used for future requests. Services that expect to be discarded if `poll_ready` fails should _not_ be used with axum. One possible approach is to only apply backpressure sensitive middleware around your entire app. This is possible because axum applications are themselves services: ```rust use axum::{ routing::get, Router, }; use tower::ServiceBuilder; # let some_backpressure_sensitive_middleware = # tower::layer::util::Identity::new(); async fn handler() { /* ... */ } let app = Router::new().route("/", get(handler)); let app = ServiceBuilder::new() .layer(some_backpressure_sensitive_middleware) .service(app); # let _: Router = app; ``` However when applying middleware around your whole application in this way you have to take care that errors are still being handled appropriately. Also note that handlers created from async functions don't care about backpressure and are always ready. So if you're not using any Tower middleware you don't have to worry about any of this. # Accessing state in middleware How to make state available to middleware depends on how the middleware is written. ## Accessing state in `axum::middleware::from_fn` Use [`axum::middleware::from_fn_with_state`](crate::middleware::from_fn_with_state). ## Accessing state in custom `tower::Layer`s ```rust use axum::{ Router, routing::get, middleware::{self, Next}, response::Response, extract::{State, Request}, }; use tower::{Layer, Service}; use std::task::{Context, Poll}; #[derive(Clone)] struct AppState {} #[derive(Clone)] struct MyLayer { state: AppState, } impl Layer for MyLayer { type Service = MyService; fn layer(&self, inner: S) -> Self::Service { MyService { inner, state: self.state.clone(), } } } #[derive(Clone)] struct MyService { inner: S, state: AppState, } impl Service> for MyService where S: Service>, { type Response = S::Response; type Error = S::Error; type Future = S::Future; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.poll_ready(cx) } fn call(&mut self, req: Request) -> Self::Future { // Do something with `self.state`. // // See `axum::RequestExt` for how to run extractors directly from // a `Request`. self.inner.call(req) } } async fn handler(_: State) {} let state = AppState {}; let app = Router::new() .route("/", get(handler)) .layer(MyLayer { state: state.clone() }) .with_state(state); # let _: axum::Router = app; ``` # Passing state from middleware to handlers State can be passed from middleware to handlers using [request extensions]: ```rust use axum::{ Router, http::StatusCode, routing::get, response::{IntoResponse, Response}, middleware::{self, Next}, extract::{Request, Extension}, }; #[derive(Clone)] struct CurrentUser { /* ... */ } async fn auth(mut req: Request, next: Next) -> Result { let auth_header = req.headers() .get(http::header::AUTHORIZATION) .and_then(|header| header.to_str().ok()); let auth_header = if let Some(auth_header) = auth_header { auth_header } else { return Err(StatusCode::UNAUTHORIZED); }; if let Some(current_user) = authorize_current_user(auth_header).await { // insert the current user into a request extension so the handler can // extract it req.extensions_mut().insert(current_user); Ok(next.run(req).await) } else { Err(StatusCode::UNAUTHORIZED) } } async fn authorize_current_user(auth_token: &str) -> Option { // ... # unimplemented!() } async fn handler( // extract the current user, set by the middleware Extension(current_user): Extension, ) { // ... } let app = Router::new() .route("/", get(handler)) .route_layer(middleware::from_fn(auth)); # let _: Router = app; ``` [Response extensions] can also be used but note that request extensions are not automatically moved to response extensions. You need to manually do that for the extensions you need. # Rewriting request URI in middleware Middleware added with [`Router::layer`] will run after routing. That means it cannot be used to run middleware that rewrites the request URI. By the time the middleware runs the routing is already done. The workaround is to wrap the middleware around the entire `Router` (this works because `Router` implements [`Service`]): ```rust use tower::Layer; use axum::{ Router, ServiceExt, // for `into_make_service` response::Response, middleware::Next, extract::Request, }; fn rewrite_request_uri(req: Request) -> Request { // ... # req } // this can be any `tower::Layer` let middleware = tower::util::MapRequestLayer::new(rewrite_request_uri); let app = Router::new(); // apply the layer around the whole `Router` // this way the middleware will run before `Router` receives the request let app_with_middleware = middleware.layer(app); # async { let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app_with_middleware.into_make_service()).await.unwrap(); # }; ``` [`tower`]: https://crates.io/crates/tower [`tower-http`]: https://crates.io/crates/tower-http [tower-guides]: https://github.com/tower-rs/tower/tree/master/guides [`axum::middleware::from_fn`]: fn@crate::middleware::from_fn [`middleware::from_fn`]: fn@crate::middleware::from_fn [tower-from-scratch-guide]: https://github.com/tower-rs/tower/blob/master/guides/building-a-middleware-from-scratch.md [`ServiceBuilder::map_request`]: tower::ServiceBuilder::map_request [`ServiceBuilder::map_response`]: tower::ServiceBuilder::map_response [`ServiceBuilder::then`]: tower::ServiceBuilder::then [`ServiceBuilder::and_then`]: tower::ServiceBuilder::and_then [`axum::middleware::from_extractor`]: fn@crate::middleware::from_extractor [`Handler::layer`]: crate::handler::Handler::layer [`Router::layer`]: crate::routing::Router::layer [`MethodRouter::layer`]: crate::routing::MethodRouter::layer [`Router::route_layer`]: crate::routing::Router::route_layer [`MethodRouter::route_layer`]: crate::routing::MethodRouter::route_layer [request extensions]: https://docs.rs/http/latest/http/request/struct.Request.html#method.extensions [Response extensions]: https://docs.rs/http/latest/http/response/struct.Response.html#method.extensions [`State`]: crate::extract::State [`Service`]: tower::Service ```rust pub mod middleware { /* ... */ } ``` ### Modules ## Module `future` Future types. ```rust pub mod future { /* ... */ } ``` ### Re-exports #### Re-export `ResponseFuture` ```rust pub use super::from_extractor::ResponseFuture as FromExtractorResponseFuture; ``` #### Re-export `ResponseFuture` ```rust pub use super::from_fn::ResponseFuture as FromFnResponseFuture; ``` #### Re-export `ResponseFuture` ```rust pub use super::map_request::ResponseFuture as MapRequestResponseFuture; ``` #### Re-export `ResponseFuture` ```rust pub use super::map_response::ResponseFuture as MapResponseResponseFuture; ``` ### Re-exports #### Re-export `from_extractor` ```rust pub use self::from_extractor::from_extractor; ``` #### Re-export `from_extractor_with_state` ```rust pub use self::from_extractor::from_extractor_with_state; ``` #### Re-export `FromExtractor` ```rust pub use self::from_extractor::FromExtractor; ``` #### Re-export `FromExtractorLayer` ```rust pub use self::from_extractor::FromExtractorLayer; ``` #### Re-export `from_fn` ```rust pub use self::from_fn::from_fn; ``` #### Re-export `from_fn_with_state` ```rust pub use self::from_fn::from_fn_with_state; ``` #### Re-export `FromFn` ```rust pub use self::from_fn::FromFn; ``` #### Re-export `FromFnLayer` ```rust pub use self::from_fn::FromFnLayer; ``` #### Re-export `Next` ```rust pub use self::from_fn::Next; ``` #### Re-export `map_request` ```rust pub use self::map_request::map_request; ``` #### Re-export `map_request_with_state` ```rust pub use self::map_request::map_request_with_state; ``` #### Re-export `IntoMapRequestResult` ```rust pub use self::map_request::IntoMapRequestResult; ``` #### Re-export `MapRequest` ```rust pub use self::map_request::MapRequest; ``` #### Re-export `MapRequestLayer` ```rust pub use self::map_request::MapRequestLayer; ``` #### Re-export `map_response` ```rust pub use self::map_response::map_response; ``` #### Re-export `map_response_with_state` ```rust pub use self::map_response::map_response_with_state; ``` #### Re-export `MapResponse` ```rust pub use self::map_response::MapResponse; ``` #### Re-export `MapResponseLayer` ```rust pub use self::map_response::MapResponseLayer; ``` #### Re-export `ResponseAxumBody` ```rust pub use self::response_axum_body::ResponseAxumBody; ``` #### Re-export `ResponseAxumBodyFuture` ```rust pub use self::response_axum_body::ResponseAxumBodyFuture; ``` #### Re-export `ResponseAxumBodyLayer` ```rust pub use self::response_axum_body::ResponseAxumBodyLayer; ``` #### Re-export `AddExtension` ```rust pub use crate::extension::AddExtension; ``` ## Module `response` Types and traits for generating responses. # Building responses Anything that implements [`IntoResponse`] can be returned from a handler. axum provides implementations for common types: ```rust,no_run use axum::{ Json, response::{Html, IntoResponse}, http::{StatusCode, Uri, header::{self, HeaderMap, HeaderName}}, }; // `()` gives an empty response async fn empty() {} // String will get a `text/plain; charset=utf-8` content-type async fn plain_text(uri: Uri) -> String { format!("Hi from {}", uri.path()) } // Bytes will get a `application/octet-stream` content-type async fn bytes() -> Vec { vec![1, 2, 3, 4] } // `Json` will get a `application/json` content-type and work with anything that // implements `serde::Serialize` async fn json() -> Json> { Json(vec!["foo".to_owned(), "bar".to_owned()]) } // `Html` will get a `text/html` content-type async fn html() -> Html<&'static str> { Html("

Hello, World!

") } // `StatusCode` gives an empty response with that status code async fn status() -> StatusCode { StatusCode::NOT_FOUND } // `HeaderMap` gives an empty response with some headers async fn headers() -> HeaderMap { let mut headers = HeaderMap::new(); headers.insert(header::SERVER, "axum".parse().unwrap()); headers } // An array of tuples also gives headers async fn array_headers() -> [(HeaderName, &'static str); 2] { [ (header::SERVER, "axum"), (header::CONTENT_TYPE, "text/plain") ] } // Use `impl IntoResponse` to avoid writing the whole type async fn impl_trait() -> impl IntoResponse { [ (header::SERVER, "axum"), (header::CONTENT_TYPE, "text/plain") ] } ``` Additionally you can return tuples to build more complex responses from individual parts. ```rust,no_run use axum::{ Json, response::IntoResponse, http::{StatusCode, HeaderMap, Uri, header}, extract::Extension, }; // `(StatusCode, impl IntoResponse)` will override the status code of the response async fn with_status(uri: Uri) -> (StatusCode, String) { (StatusCode::NOT_FOUND, format!("Not Found: {}", uri.path())) } // Use `impl IntoResponse` to avoid having to type the whole type async fn impl_trait(uri: Uri) -> impl IntoResponse { (StatusCode::NOT_FOUND, format!("Not Found: {}", uri.path())) } // `(HeaderMap, impl IntoResponse)` to add additional headers async fn with_headers() -> impl IntoResponse { let mut headers = HeaderMap::new(); headers.insert(header::CONTENT_TYPE, "text/plain".parse().unwrap()); (headers, "foo") } // Or an array of tuples to more easily build the headers async fn with_array_headers() -> impl IntoResponse { ([(header::CONTENT_TYPE, "text/plain")], "foo") } // Use string keys for custom headers async fn with_array_headers_custom() -> impl IntoResponse { ([("x-custom", "custom")], "foo") } // `(StatusCode, headers, impl IntoResponse)` to set status and add headers // `headers` can be either a `HeaderMap` or an array of tuples async fn with_status_and_array_headers() -> impl IntoResponse { ( StatusCode::NOT_FOUND, [(header::CONTENT_TYPE, "text/plain")], "foo", ) } // `(Extension<_>, impl IntoResponse)` to set response extensions async fn with_status_extensions() -> impl IntoResponse { ( Extension(Foo("foo")), "foo", ) } #[derive(Clone)] struct Foo(&'static str); // Or mix and match all the things async fn all_the_things(uri: Uri) -> impl IntoResponse { let mut header_map = HeaderMap::new(); if uri.path() == "/" { header_map.insert(header::SERVER, "axum".parse().unwrap()); } ( // set status code StatusCode::NOT_FOUND, // headers with an array [("x-custom", "custom")], // some extensions Extension(Foo("foo")), Extension(Foo("bar")), // more headers, built dynamically header_map, // and finally the body "foo", ) } ``` In general you can return tuples like: - `(StatusCode, impl IntoResponse)` - `(Parts, impl IntoResponse)` - `(Response<()>, impl IntoResponse)` - `(T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`]. - `(StatusCode, T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`]. - `(Parts, T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`]. - `(Response<()>, T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`]. This means you cannot accidentally override the status or body as [`IntoResponseParts`] only allows setting headers and extensions. Use [`Response`] for more low level control: ```rust,no_run use axum::{ Json, response::{IntoResponse, Response}, body::Body, http::StatusCode, }; async fn response() -> Response { Response::builder() .status(StatusCode::NOT_FOUND) .header("x-foo", "custom header") .body(Body::from("not found")) .unwrap() } ``` # Returning different response types If you need to return multiple response types, and `Result` isn't appropriate, you can call `.into_response()` to turn things into `axum::response::Response`: ```rust use axum::{ response::{IntoResponse, Redirect, Response}, http::StatusCode, }; async fn handle() -> Response { if something() { "All good!".into_response() } else if something_else() { ( StatusCode::INTERNAL_SERVER_ERROR, "Something went wrong...", ).into_response() } else { Redirect::to("/").into_response() } } fn something() -> bool { // ... # true } fn something_else() -> bool { // ... # true } ``` # Regarding `impl IntoResponse` You can use `impl IntoResponse` as the return type from handlers to avoid typing large types. For example ```rust use axum::http::StatusCode; async fn handler() -> (StatusCode, [(&'static str, &'static str); 1], &'static str) { (StatusCode::OK, [("x-foo", "bar")], "Hello, World!") } ``` Becomes easier using `impl IntoResponse`: ```rust use axum::{http::StatusCode, response::IntoResponse}; async fn impl_into_response() -> impl IntoResponse { (StatusCode::OK, [("x-foo", "bar")], "Hello, World!") } ``` However `impl IntoResponse` has a few limitations. Firstly it can only be used to return a single type: ```rust,compile_fail use axum::{http::StatusCode, response::IntoResponse}; async fn handler() -> impl IntoResponse { if check_something() { StatusCode::NOT_FOUND } else { "Hello, World!" } } fn check_something() -> bool { # false // ... } ``` This function returns either a `StatusCode` or a `&'static str` which `impl Trait` doesn't allow. Secondly `impl IntoResponse` can lead to type inference issues when used with `Result` and `?`: ```rust,compile_fail use axum::{http::StatusCode, response::IntoResponse}; async fn handler() -> impl IntoResponse { create_thing()?; Ok(StatusCode::CREATED) } fn create_thing() -> Result<(), StatusCode> { # Ok(()) // ... } ``` This is because `?` supports using the [`From`] trait to convert to a different error type but it doesn't know which type to convert to, because we only specified `impl IntoResponse` as the return type. `Result` doesn't always work either: ```rust,compile_fail use axum::{http::StatusCode, response::IntoResponse}; async fn handler() -> Result { create_thing()?; Ok(StatusCode::CREATED) } fn create_thing() -> Result<(), StatusCode> { # Ok(()) // ... } ``` The solution is to use a concrete error type, such as `Result`: ```rust use axum::{http::StatusCode, response::IntoResponse}; async fn handler() -> Result { create_thing()?; Ok(StatusCode::CREATED) } fn create_thing() -> Result<(), StatusCode> { # Ok(()) // ... } ``` Because of this it is generally not recommended to use `impl IntoResponse` unless you're familiar with the details of how `impl Trait` works. [`IntoResponse`]: crate::response::IntoResponse [`IntoResponseParts`]: crate::response::IntoResponseParts [`StatusCode`]: http::StatusCode ```rust pub mod response { /* ... */ } ``` ### Modules ## Module `sse` Server-Sent Events (SSE) responses. # Example ``` use axum::{ Router, routing::get, response::sse::{Event, KeepAlive, Sse}, }; use std::{time::Duration, convert::Infallible}; use tokio_stream::StreamExt as _ ; use futures_util::stream::{self, Stream}; let app = Router::new().route("/sse", get(sse_handler)); async fn sse_handler() -> Sse>> { // A `Stream` that repeats an event every second let stream = stream::repeat_with(|| Event::default().data("hi!")) .map(Ok) .throttle(Duration::from_secs(1)); Sse::new(stream).keep_alive(KeepAlive::default()) } # let _: Router = app; ``` ```rust pub mod sse { /* ... */ } ``` ### Types #### Struct `Sse` **Attributes:** - `MustUse { reason: None }` An SSE response ```rust pub struct Sse { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn new(stream: S) -> Self where S: TryStream + Send + ''static, ::Error: Into { /* ... */ } ``` Create a new [`Sse`] response that will respond with the given stream of - ```rust pub fn keep_alive(self: Self, keep_alive: KeepAlive) -> Sse> { /* ... */ } ``` Configure the interval between keep-alive messages. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Sse { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **HandlerWithoutStateExt** - ```rust fn into_service(self: Self) -> HandlerService { /* ... */ } ``` - ```rust fn into_make_service(self: Self) -> IntoMakeService> { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo, C> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `Event` **Attributes:** - `MustUse { reason: None }` Server-sent event ```rust pub struct Event { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn into_data_writer(self: Self) -> EventDataWriter { /* ... */ } ``` Use this [`Event`] as a [`EventDataWriter`] to write custom data. - ```rust pub fn data(self: Self, data: T) -> Self where T: AsRef { /* ... */ } ``` Set the event's data data field(s) (`data: `) - ```rust pub fn json_data(self: Self, data: T) -> Result where T: serde_core::Serialize { /* ... */ } ``` Set the event's data field to a value serialized as unformatted JSON (`data: `). - ```rust pub fn comment(self: Self, comment: T) -> Event where T: AsRef { /* ... */ } ``` Set the event's comment field (`:`). - ```rust pub fn event(self: Self, event: T) -> Event where T: AsRef { /* ... */ } ``` Set the event's name field (`event:`). - ```rust pub fn retry(self: Self, duration: Duration) -> Event { /* ... */ } ``` Set the event's retry timeout field (`retry: `). - ```rust pub fn id(self: Self, id: T) -> Event where T: AsRef { /* ... */ } ``` Set the event's identifier field (`id:`). ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Event { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `EventDataWriter` **Attributes:** - `MustUse { reason: None }` Expose [`Event`] as a [`std::fmt::Write`] such that any form of data can be written as data safely. This also ensures that newline characters `\r` and `\n` correctly trigger a split with a new `data: ` prefix. # Panics Panics if any `data` has already been written prior to the first write of this [`EventDataWriter`] instance. ```rust pub struct EventDataWriter { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn into_event(self: Self) -> Event { /* ... */ } ``` Consume the [`EventDataWriter`] and return the [`Event`] once again. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** - **Write** - ```rust fn write_str(self: &mut Self, s: &str) -> fmt::Result { /* ... */ } ``` #### Struct `KeepAlive` **Attributes:** - `MustUse { reason: None }` Configure the interval between keep-alive messages, the content of each message, and the associated stream. ```rust pub struct KeepAlive { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn new() -> Self { /* ... */ } ``` Create a new `KeepAlive`. - ```rust pub fn interval(self: Self, time: Duration) -> Self { /* ... */ } ``` Customize the interval between keep-alive messages. - ```rust pub fn text(self: Self, text: I) -> Self where I: AsRef { /* ... */ } ``` Customize the text of the keep-alive message. - ```rust pub fn event(self: Self, event: Event) -> Self { /* ... */ } ``` Customize the event of the keep-alive message. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> KeepAlive { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `KeepAliveStream` A wrapper around a stream that produces keep-alive events ```rust pub struct KeepAliveStream { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Stream** - ```rust fn poll_next(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll::Item>> { /* ... */ } ``` - **StreamExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **TryStream** - ```rust fn try_poll_next(self: Pin<&mut S>, cx: &mut Context<''_>) -> Poll::Ok, ::Error>>> { /* ... */ } ``` - **TryStreamExt** - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Types #### Struct `Html` **Attributes:** - `MustUse { reason: None }` An HTML response. Will automatically get `Content-Type: text/html`. ```rust pub struct Html(pub T); ``` ##### Fields | Index | Type | Documentation | |-------|------|---------------| | 0 | `T` | | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Html { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Copy** - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - ```rust fn from(t: never) -> T { /* ... */ } ``` - ```rust fn from(inner: T) -> Self { /* ... */ } ``` - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **HandlerWithoutStateExt** - ```rust fn into_service(self: Self) -> HandlerService { /* ... */ } ``` - ```rust fn into_make_service(self: Self) -> IntoMakeService> { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo, C> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `NoContent` An empty response with 204 No Content status. Due to historical and implementation reasons, the `IntoResponse` implementation of `()` (unit type) returns an empty response with 200 [`StatusCode::OK`] status. If you specifically want a 204 [`StatusCode::NO_CONTENT`] status, you can use either `StatusCode` type directly, or this shortcut struct for self-documentation. ``` use axum::{extract::Path, response::NoContent}; async fn delete_user(Path(user): Path) -> Result { // ...access database... # drop(user); Ok(NoContent) } ``` ```rust pub struct NoContent; ``` ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> NoContent { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Copy** - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **HandlerWithoutStateExt** - ```rust fn into_service(self: Self) -> HandlerService { /* ... */ } ``` - ```rust fn into_make_service(self: Self) -> IntoMakeService> { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo, C> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoResponse** - ```rust fn into_response(self: Self) -> Response { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Re-exports #### Re-export `Json` **Attributes:** - `Other("#[doc(no_inline)]")` - `Other("#[(feature = \"json\")]")` ```rust pub use crate::Json; ``` #### Re-export `Form` **Attributes:** - `Other("#[(feature = \"form\")]")` - `Other("#[doc(no_inline)]")` ```rust pub use crate::form::Form; ``` #### Re-export `Extension` **Attributes:** - `Other("#[doc(no_inline)]")` ```rust pub use crate::Extension; ``` #### Re-export `AppendHeaders` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::response::AppendHeaders; ``` #### Re-export `ErrorResponse` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::response::ErrorResponse; ``` #### Re-export `IntoResponse` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::response::IntoResponse; ``` #### Re-export `IntoResponseParts` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::response::IntoResponseParts; ``` #### Re-export `Response` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::response::Response; ``` #### Re-export `ResponseParts` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::response::ResponseParts; ``` #### Re-export `Result` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::response::Result; ``` #### Re-export `Redirect` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use self::redirect::Redirect; ``` #### Re-export `Sse` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use sse::Sse; ``` ## Module `routing` Routing between [`Service`]s and handlers. ```rust pub mod routing { /* ... */ } ``` ### Modules ## Module `future` Future types. ```rust pub mod future { /* ... */ } ``` ### Re-exports #### Re-export `IntoMakeServiceFuture` ```rust pub use super::into_make_service::IntoMakeServiceFuture; ``` #### Re-export `InfallibleRouteFuture` ```rust pub use super::route::InfallibleRouteFuture; ``` #### Re-export `RouteFuture` ```rust pub use super::route::RouteFuture; ``` ## Module `method_routing` Route to services and handlers based on HTTP methods. ```rust pub mod method_routing { /* ... */ } ``` ### Types #### Struct `MethodRouter` **Attributes:** - `MustUse { reason: None }` A [`Service`] that accepts requests based on a [`MethodFilter`] and allows chaining additional handlers and services. # When does `MethodRouter` implement [`Service`]? Whether or not `MethodRouter` implements [`Service`] depends on the state type it requires. ``` use tower::Service; use axum::{routing::get, extract::{State, Request}, body::Body}; // this `MethodRouter` doesn't require any state, i.e. the state is `()`, let method_router = get(|| async {}); // and thus it implements `Service` assert_service(method_router); // this requires a `String` and doesn't implement `Service` let method_router = get(|_: State| async {}); // until you provide the `String` with `.with_state(...)` let method_router_with_state = method_router.with_state(String::new()); // and then it implements `Service` assert_service(method_router_with_state); // helper to check that a value implements `Service` fn assert_service(service: S) where S: Service, {} ``` ```rust pub struct MethodRouter { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn on(self: Self, filter: MethodFilter, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will accept requests matching the given - ```rust pub fn connect(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will only accept `CONNECT` requests. - ```rust pub fn delete(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will only accept `DELETE` requests. - ```rust pub fn get(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will only accept `GET` requests. - ```rust pub fn head(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will only accept `HEAD` requests. - ```rust pub fn options(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will only accept `OPTIONS` requests. - ```rust pub fn patch(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will only accept `PATCH` requests. - ```rust pub fn post(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will only accept `POST` requests. - ```rust pub fn put(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will only accept `PUT` requests. - ```rust pub fn trace(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Chain an additional handler that will only accept `TRACE` requests. - ```rust pub fn fallback(self: Self, handler: H) -> Self where H: Handler, T: ''static, S: Send + Sync + ''static { /* ... */ } ``` Add a fallback [`Handler`] to the router. - ```rust pub fn into_make_service(self: Self) -> IntoMakeService { /* ... */ } ``` Convert the router into a [`MakeService`]. - ```rust pub fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo { /* ... */ } ``` Convert the router into a [`MakeService`] which stores information - ```rust pub fn new() -> Self { /* ... */ } ``` Create a default `MethodRouter` that will respond with `405 Method Not Allowed` to all - ```rust pub fn with_state(self: Self, state: S) -> MethodRouter { /* ... */ } ``` Provide the state for the router. - ```rust pub fn on_service(self: Self, filter: MethodFilter, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will accept requests matching the given - ```rust pub fn connect_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will only accept `CONNECT` requests. - ```rust pub fn delete_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will only accept `DELETE` requests. - ```rust pub fn get_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will only accept `GET` requests. - ```rust pub fn head_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will only accept `HEAD` requests. - ```rust pub fn options_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will only accept `OPTIONS` requests. - ```rust pub fn patch_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will only accept `PATCH` requests. - ```rust pub fn post_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will only accept `POST` requests. - ```rust pub fn put_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will only accept `PUT` requests. - ```rust pub fn trace_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Chain an additional service that will only accept `TRACE` requests. - ```rust pub fn fallback_service(self: Self, svc: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static { /* ... */ } ``` Add a fallback service to the router. - ```rust pub fn layer(self: Self, layer: L) -> MethodRouter where L: Layer> + Clone + Send + Sync + ''static, ::Service: Service + Clone + Send + Sync + ''static, <::Service as Service>::Response: IntoResponse + ''static, <::Service as Service>::Error: Into + ''static, <::Service as Service>::Future: Send + ''static, E: ''static, S: ''static, NewError: ''static { /* ... */ } ``` Apply a [`tower::Layer`] to all routes in the router. - ```rust pub fn route_layer(self: Self, layer: L) -> MethodRouter where L: Layer> + Clone + Send + Sync + ''static, ::Service: Service + Clone + Send + Sync + ''static, <::Service as Service>::Response: IntoResponse + ''static, <::Service as Service>::Future: Send + ''static, E: ''static, S: ''static { /* ... */ } ``` Apply a [`tower::Layer`] to the router that will only run if the request matches - ```rust pub fn merge(self: Self, other: MethodRouter) -> Self { /* ... */ } ``` Merge two routers into one. - ```rust pub fn handle_error(self: Self, f: F) -> MethodRouter where F: Clone + Send + Sync + ''static, HandleError, F, T>: Service, , F, T> as Service>::Future: Send, , F, T> as Service>::Response: IntoResponse + Send, T: ''static, E: ''static, S: ''static { /* ... */ } ``` Apply a [`HandleErrorLayer`]. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Self { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Handler** - ```rust fn call(self: Self, req: Request, state: S) -> ::Future { /* ... */ } ``` - **HandlerWithoutStateExt** - ```rust fn into_service(self: Self) -> HandlerService { /* ... */ } ``` - ```rust fn into_make_service(self: Self) -> IntoMakeService> { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo, C> { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **MakeService** - ```rust fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll>::MakeError>> { /* ... */ } ``` - ```rust fn make_service(self: &mut Self, target: Target) -> >::Future { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **Service** - ```rust fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> ::Future { /* ... */ } ``` - **ServiceExt** - ```rust fn into_make_service(self: Self) -> IntoMakeService { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo { /* ... */ } ``` - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Functions #### Function `connect_service` Route `CONNECT` requests to the given service. See [`MethodFilter::CONNECT`] for when you'd want to use this, and [`get_service`] for an example. ```rust pub fn connect_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `delete_service` Route `DELETE` requests to the given service. See [`get_service`] for an example. ```rust pub fn delete_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `get_service` Route `GET` requests to the given service. # Example ```rust use axum::{ extract::Request, Router, routing::get_service, body::Body, }; use http::Response; use std::convert::Infallible; let service = tower::service_fn(|request: Request| async { Ok::<_, Infallible>(Response::new(Body::empty())) }); // Requests to `GET /` will go to `service`. let app = Router::new().route("/", get_service(service)); # let _: Router = app; ``` Note that `get` routes will also be called for `HEAD` requests but will have the response body removed. Make sure to add explicit `HEAD` routes afterwards. ```rust pub fn get_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `head_service` Route `HEAD` requests to the given service. See [`get_service`] for an example. ```rust pub fn head_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `options_service` Route `OPTIONS` requests to the given service. See [`get_service`] for an example. ```rust pub fn options_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `patch_service` Route `PATCH` requests to the given service. See [`get_service`] for an example. ```rust pub fn patch_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `post_service` Route `POST` requests to the given service. See [`get_service`] for an example. ```rust pub fn post_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `put_service` Route `PUT` requests to the given service. See [`get_service`] for an example. ```rust pub fn put_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `trace_service` Route `TRACE` requests to the given service. See [`get_service`] for an example. ```rust pub fn trace_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `on_service` Route requests with the given method to the service. # Example ```rust use axum::{ extract::Request, routing::on, Router, body::Body, routing::{MethodFilter, on_service}, }; use http::Response; use std::convert::Infallible; let service = tower::service_fn(|request: Request| async { Ok::<_, Infallible>(Response::new(Body::empty())) }); // Requests to `POST /` will go to `service`. let app = Router::new().route("/", on_service(MethodFilter::POST, service)); # let _: Router = app; ``` ```rust pub fn on_service(filter: crate::routing::MethodFilter, svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `any_service` Route requests to the given service regardless of its method. # Example ```rust use axum::{ extract::Request, Router, routing::any_service, body::Body, }; use http::Response; use std::convert::Infallible; let service = tower::service_fn(|request: Request| async { Ok::<_, Infallible>(Response::new(Body::empty())) }); // All requests to `/` will go to `service`. let app = Router::new().route("/", any_service(service)); # let _: Router = app; ``` Additional methods can still be chained: ```rust use axum::{ extract::Request, Router, routing::any_service, body::Body, }; use http::Response; use std::convert::Infallible; let service = tower::service_fn(|request: Request| async { # Ok::<_, Infallible>(Response::new(Body::empty())) // ... }); let other_service = tower::service_fn(|request: Request| async { # Ok::<_, Infallible>(Response::new(Body::empty())) // ... }); // `POST /` goes to `other_service`. All other requests go to `service` let app = Router::new().route("/", any_service(service).post_service(other_service)); # let _: Router = app; ``` ```rust pub fn any_service(svc: T) -> MethodRouter::Error> where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse + ''static, ::Future: Send + ''static, S: Clone { /* ... */ } ``` #### Function `connect` Route `CONNECT` requests to the given handler. See [`MethodFilter::CONNECT`] for when you'd want to use this, and [`get`] for an example. ```rust pub fn connect(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `delete` Route `DELETE` requests to the given handler. See [`get`] for an example. ```rust pub fn delete(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `get` Route `GET` requests to the given handler. # Example ```rust use axum::{ routing::get, Router, }; async fn handler() {} // Requests to `GET /` will go to `handler`. let app = Router::new().route("/", get(handler)); # let _: Router = app; ``` Note that `get` routes will also be called for `HEAD` requests but will have the response body removed. Make sure to add explicit `HEAD` routes afterwards. ```rust pub fn get(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `head` Route `HEAD` requests to the given handler. See [`get`] for an example. ```rust pub fn head(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `options` Route `OPTIONS` requests to the given handler. See [`get`] for an example. ```rust pub fn options(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `patch` Route `PATCH` requests to the given handler. See [`get`] for an example. ```rust pub fn patch(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `post` Route `POST` requests to the given handler. See [`get`] for an example. ```rust pub fn post(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `put` Route `PUT` requests to the given handler. See [`get`] for an example. ```rust pub fn put(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `trace` Route `TRACE` requests to the given handler. See [`get`] for an example. ```rust pub fn trace(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `on` Route requests with the given method to the handler. # Example ```rust use axum::{ routing::on, Router, routing::MethodFilter, }; async fn handler() {} // Requests to `POST /` will go to `handler`. let app = Router::new().route("/", on(MethodFilter::POST, handler)); # let _: Router = app; ``` ```rust pub fn on(filter: crate::routing::MethodFilter, handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` #### Function `any` Route requests with the given handler regardless of the method. # Example ```rust use axum::{ routing::any, Router, }; async fn handler() {} // All requests to `/` will go to `handler`. let app = Router::new().route("/", any(handler)); # let _: Router = app; ``` Additional methods can still be chained: ```rust use axum::{ routing::any, Router, }; async fn handler() {} async fn other_handler() {} // `POST /` goes to `other_handler`. All other requests go to `handler` let app = Router::new().route("/", any(handler).post(other_handler)); # let _: Router = app; ``` ```rust pub fn any(handler: H) -> MethodRouter where H: Handler, T: ''static, S: Clone + Send + Sync + ''static { /* ... */ } ``` ### Types #### Struct `Router` **Attributes:** - `MustUse { reason: None }` The router type for composing handlers and services. `Router` means a router that is _missing_ a state of type `S` to be able to handle requests. Thus, only `Router<()>` (i.e. without missing state) can be passed to [`serve`]. See [`Router::with_state`] for more details. [`serve`]: crate::serve() ```rust pub struct Router { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn new() -> Self { /* ... */ } ``` Create a new `Router`. - ```rust pub fn without_v07_checks(self: Self) -> Self { /* ... */ } ``` Turn off checks for compatibility with route matching syntax from 0.7. - ```rust pub fn route(self: Self, path: &str, method_router: MethodRouter) -> Self { /* ... */ } ``` Add another route to the router. - ```rust pub fn route_service(self: Self, path: &str, service: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse, ::Future: Send + ''static { /* ... */ } ``` Add another route to the router that calls a [`Service`]. - ```rust pub fn nest(self: Self, path: &str, router: Router) -> Self { /* ... */ } ``` Nest a [`Router`] at some path. - ```rust pub fn nest_service(self: Self, path: &str, service: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse, ::Future: Send + ''static { /* ... */ } ``` Like [`nest`](Self::nest), but accepts an arbitrary `Service`. - ```rust pub fn merge(self: Self, other: R) -> Self where R: Into> { /* ... */ } ``` Merge the paths and fallbacks of two routers into a single [`Router`]. - ```rust pub fn layer(self: Self, layer: L) -> Router where L: Layer + Clone + Send + Sync + ''static, ::Service: Service + Clone + Send + Sync + ''static, <::Service as Service>::Response: IntoResponse + ''static, <::Service as Service>::Error: Into + ''static, <::Service as Service>::Future: Send + ''static { /* ... */ } ``` Apply a [`tower::Layer`] to all routes in the router. - ```rust pub fn route_layer(self: Self, layer: L) -> Self where L: Layer + Clone + Send + Sync + ''static, ::Service: Service + Clone + Send + Sync + ''static, <::Service as Service>::Response: IntoResponse + ''static, <::Service as Service>::Error: Into + ''static, <::Service as Service>::Future: Send + ''static { /* ... */ } ``` Apply a [`tower::Layer`] to the router that will only run if the request matches - ```rust pub fn has_routes(self: &Self) -> bool { /* ... */ } ``` True if the router currently has at least one route added. - ```rust pub fn fallback(self: Self, handler: H) -> Self where H: Handler, T: ''static { /* ... */ } ``` Add a fallback [`Handler`] to the router. - ```rust pub fn fallback_service(self: Self, service: T) -> Self where T: Service + Clone + Send + Sync + ''static, ::Response: IntoResponse, ::Future: Send + ''static { /* ... */ } ``` Add a fallback [`Service`] to the router. - ```rust pub fn method_not_allowed_fallback(self: Self, handler: H) -> Self where H: Handler, T: ''static { /* ... */ } ``` Add a fallback [`Handler`] for the case where a route exists, but the method of the request is not supported. - ```rust pub fn reset_fallback(self: Self) -> Self { /* ... */ } ``` Reset the fallback to its default. - ```rust pub fn with_state(self: Self, state: S) -> Router { /* ... */ } ``` Provide the state for the router. State passed to this method is global and will be used - ```rust pub fn as_service(self: &mut Self) -> RouterAsService<''_, B, S> { /* ... */ } ``` Convert the router into a borrowed [`Service`] with a fixed request body type, to aid type - ```rust pub fn into_service(self: Self) -> RouterIntoService { /* ... */ } ``` Convert the router into an owned [`Service`] with a fixed request body type, to aid type - ```rust pub fn into_make_service(self: Self) -> IntoMakeService { /* ... */ } ``` Convert this router into a [`MakeService`], that is a [`Service`] whose - ```rust pub fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo { /* ... */ } ``` Convert this router into a [`MakeService`], that will store `C`'s ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Self { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **Default** - ```rust fn default() -> Self { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **MakeService** - ```rust fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll>::MakeError>> { /* ... */ } ``` - ```rust fn make_service(self: &mut Self, target: Target) -> >::Future { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **Service** - ```rust fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - **ServiceExt** - ```rust fn into_make_service(self: Self) -> IntoMakeService { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo { /* ... */ } ``` - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `RouterAsService` A [`Router`] converted into a borrowed [`Service`] with a fixed body type. See [`Router::as_service`] for more details. ```rust pub struct RouterAsService<''a, B, S = ()> { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **Service** - ```rust fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - **ServiceExt** - ```rust fn into_make_service(self: Self) -> IntoMakeService { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo { /* ... */ } ``` - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `RouterIntoService` A [`Router`] converted into an owned [`Service`] with a fixed body type. See [`Router::into_service`] for more details. ```rust pub struct RouterIntoService { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Clone** - ```rust fn clone(self: &Self) -> Self { /* ... */ } ``` - **CloneToUninit** - ```rust unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **FromRef** - ```rust fn from_ref(input: &T) -> T { /* ... */ } ``` - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **Service** - ```rust fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, req: Request) -> ::Future { /* ... */ } ``` - **ServiceExt** - ```rust fn into_make_service(self: Self) -> IntoMakeService { /* ... */ } ``` - ```rust fn into_make_service_with_connect_info(self: Self) -> IntoMakeServiceWithConnectInfo { /* ... */ } ``` - **Sync** - **ToOwned** - ```rust fn to_owned(self: &Self) -> T { /* ... */ } ``` - ```rust fn clone_into(self: &Self, target: &mut T) { /* ... */ } ``` - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Re-exports #### Re-export `IntoMakeService` ```rust pub use self::into_make_service::IntoMakeService; ``` #### Re-export `MethodFilter` ```rust pub use self::method_filter::MethodFilter; ``` #### Re-export `Route` ```rust pub use self::route::Route; ``` #### Re-export `any` ```rust pub use self::method_routing::any; ``` #### Re-export `any_service` ```rust pub use self::method_routing::any_service; ``` #### Re-export `connect` ```rust pub use self::method_routing::connect; ``` #### Re-export `connect_service` ```rust pub use self::method_routing::connect_service; ``` #### Re-export `delete` ```rust pub use self::method_routing::delete; ``` #### Re-export `delete_service` ```rust pub use self::method_routing::delete_service; ``` #### Re-export `get` ```rust pub use self::method_routing::get; ``` #### Re-export `get_service` ```rust pub use self::method_routing::get_service; ``` #### Re-export `head` ```rust pub use self::method_routing::head; ``` #### Re-export `head_service` ```rust pub use self::method_routing::head_service; ``` #### Re-export `on` ```rust pub use self::method_routing::on; ``` #### Re-export `on_service` ```rust pub use self::method_routing::on_service; ``` #### Re-export `options` ```rust pub use self::method_routing::options; ``` #### Re-export `options_service` ```rust pub use self::method_routing::options_service; ``` #### Re-export `patch` ```rust pub use self::method_routing::patch; ``` #### Re-export `patch_service` ```rust pub use self::method_routing::patch_service; ``` #### Re-export `post` ```rust pub use self::method_routing::post; ``` #### Re-export `post_service` ```rust pub use self::method_routing::post_service; ``` #### Re-export `put` ```rust pub use self::method_routing::put; ``` #### Re-export `put_service` ```rust pub use self::method_routing::put_service; ``` #### Re-export `trace` ```rust pub use self::method_routing::trace; ``` #### Re-export `trace_service` ```rust pub use self::method_routing::trace_service; ``` #### Re-export `MethodRouter` ```rust pub use self::method_routing::MethodRouter; ``` ## Module `serve` **Attributes:** - `Other("#[(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")` Serve services. ```rust pub mod serve { /* ... */ } ``` ### Types #### Struct `Serve` **Attributes:** - `Other("#[(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")` - `MustUse { reason: Some("futures must be awaited or polled") }` Future returned by [`serve`]. ```rust pub struct Serve { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn with_graceful_shutdown(self: Self, signal: F) -> WithGracefulShutdown where F: Future + Send + ''static { /* ... */ } ``` Prepares a server to handle graceful shutdown when the provided future completes. - ```rust pub fn local_addr(self: &Self) -> io::Result<::Addr> { /* ... */ } ``` Returns the local address this server is bound to. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoFuture** - ```rust fn into_future(self: Self) -> ::IntoFuture { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `WithGracefulShutdown` **Attributes:** - `Other("#[(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")` - `MustUse { reason: Some("futures must be awaited or polled") }` Serve future with graceful shutdown enabled. ```rust pub struct WithGracefulShutdown { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn local_addr(self: &Self) -> io::Result<::Addr> { /* ... */ } ``` Returns the local address this server is bound to. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **IntoFuture** - ```rust fn into_future(self: Self) -> ::IntoFuture { /* ... */ } ``` - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** #### Struct `IncomingStream` An incoming stream. Used with [`serve`] and [`IntoMakeServiceWithConnectInfo`]. [`IntoMakeServiceWithConnectInfo`]: crate::extract::connect_info::IntoMakeServiceWithConnectInfo ```rust pub struct IncomingStream<''a, L> { // Some fields omitted } ``` ##### Fields | Name | Type | Documentation | |------|------|---------------| | *private fields* | ... | *Some fields have been omitted* | ##### Implementations ###### Methods - ```rust pub fn io(self: &Self) -> &::Io { /* ... */ } ``` Get a reference to the inner IO type. - ```rust pub fn remote_addr(self: &Self) -> &::Addr { /* ... */ } ``` Returns the remote address that this stream is bound to. ###### Trait Implementations - **Any** - ```rust fn type_id(self: &Self) -> TypeId { /* ... */ } ``` - **Borrow** - ```rust fn borrow(self: &Self) -> &T { /* ... */ } ``` - **BorrowMut** - ```rust fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ } ``` - **Connected** - ```rust fn connect_info(stream: serve::IncomingStream<''_, TcpListener>) -> Self { /* ... */ } ``` - ```rust fn connect_info(stream: serve::IncomingStream<''a, serve::TapIo>) -> Self { /* ... */ } ``` - **Debug** - ```rust fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ } ``` - **ErasedDestructor** - **Freeze** - **From** - ```rust fn from(t: T) -> T { /* ... */ } ``` Returns the argument unchanged. - **Instrument** - **Into** - ```rust fn into(self: Self) -> U { /* ... */ } ``` Calls `U::from(self)`. - **PolicyExt** - ```rust fn and(self: Self, other: P) -> And where T: Policy, P: Policy { /* ... */ } ``` - ```rust fn or(self: Self, other: P) -> Or where T: Policy, P: Policy { /* ... */ } ``` - **RefUnwindSafe** - **Same** - **Send** - **Service** - ```rust fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> ::Future { /* ... */ } ``` - ```rust fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll::Error>> { /* ... */ } ``` - ```rust fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> ::Future { /* ... */ } ``` - **ServiceExt** - **Sync** - **TryFrom** - ```rust fn try_from(value: U) -> Result>::Error> { /* ... */ } ``` - **TryInto** - ```rust fn try_into(self: Self) -> Result>::Error> { /* ... */ } ``` - **Unpin** - **UnwindSafe** - **VZip** - ```rust fn vzip(self: Self) -> V { /* ... */ } ``` - **WithSubscriber** ### Functions #### Function `serve` **Attributes:** - `Other("#[(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")` Serve the service with the supplied listener. This method of running a service is intentionally simple and doesn't support any configuration. Use hyper or hyper-util if you need configuration. It supports both HTTP/1 as well as HTTP/2. # Examples Serving a [`Router`]: ``` use axum::{Router, routing::get}; # async { let router = Router::new().route("/", get(|| async { "Hello, World!" })); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, router).await.unwrap(); # }; ``` See also [`Router::into_make_service_with_connect_info`]. Serving a [`MethodRouter`]: ``` use axum::routing::get; # async { let router = get(|| async { "Hello, World!" }); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, router).await.unwrap(); # }; ``` See also [`MethodRouter::into_make_service_with_connect_info`]. Serving a [`Handler`]: ``` use axum::handler::HandlerWithoutStateExt; # async { async fn handler() -> &'static str { "Hello, World!" } let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, handler.into_make_service()).await.unwrap(); # }; ``` See also [`HandlerWithoutStateExt::into_make_service_with_connect_info`] and [`HandlerService::into_make_service_with_connect_info`]. # Return Value Although this future resolves to `io::Result<()>`, it will never actually complete or return an error. Errors on the TCP socket will be handled by sleeping for a short while (currently, one second). [`Router`]: crate::Router [`Router::into_make_service_with_connect_info`]: crate::Router::into_make_service_with_connect_info [`MethodRouter`]: crate::routing::MethodRouter [`MethodRouter::into_make_service_with_connect_info`]: crate::routing::MethodRouter::into_make_service_with_connect_info [`Handler`]: crate::handler::Handler [`HandlerWithoutStateExt::into_make_service_with_connect_info`]: crate::handler::HandlerWithoutStateExt::into_make_service_with_connect_info [`HandlerService::into_make_service_with_connect_info`]: crate::handler::HandlerService::into_make_service_with_connect_info ```rust pub fn serve(listener: L, make_service: M) -> Serve where L: Listener, M: for<''a> Service, Error = std::convert::Infallible, Response = S>, S: Service + Clone + Send + ''static, ::Future: Send { /* ... */ } ``` ### Re-exports #### Re-export `Listener` ```rust pub use self::listener::Listener; ``` #### Re-export `ListenerExt` ```rust pub use self::listener::ListenerExt; ``` #### Re-export `TapIo` ```rust pub use self::listener::TapIo; ``` ## Module `test_helpers` **Attributes:** - `Other("#[(any(test, feature = \"__private\"))]")` - `Other("#[allow(missing_docs, missing_debug_implementations, clippy::print_stdout)]")` - `Other("#[allow(clippy::disallowed_names)]")` ```rust pub mod test_helpers { /* ... */ } ``` ### Re-exports #### Re-export `self::test_client::*` ```rust pub use self::test_client::*; ``` ## Re-exports ### Re-export `http` **Attributes:** - `Other("#[doc(no_inline)]")` ```rust pub use http; ``` ### Re-export `Extension` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use self::extension::Extension; ``` ### Re-export `Json` **Attributes:** - `Other("#[doc(inline)]")` - `Other("#[(feature = \"json\")]")` ```rust pub use self::json::Json; ``` ### Re-export `Router` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use self::routing::Router; ``` ### Re-export `Form` **Attributes:** - `Other("#[doc(inline)]")` - `Other("#[(feature = \"form\")]")` ```rust pub use self::form::Form; ``` ### Re-export `BoxError` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::BoxError; ``` ### Re-export `Error` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::Error; ``` ### Re-export `RequestExt` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::RequestExt; ``` ### Re-export `RequestPartsExt` **Attributes:** - `Other("#[doc(inline)]")` ```rust pub use axum_core::RequestPartsExt; ``` ### Re-export `debug_handler` **Attributes:** - `Other("#[(feature = \"macros\")]")` ```rust pub use axum_macros::debug_handler; ``` ### Re-export `debug_middleware` **Attributes:** - `Other("#[(feature = \"macros\")]")` ```rust pub use axum_macros::debug_middleware; ``` ### Re-export `serve` **Attributes:** - `Other("#[(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")` - `Other("#[doc(inline)]")` ```rust pub use self::serve::serve; ``` ### Re-export `ServiceExt` ```rust pub use self::service_ext::ServiceExt; ```