### Basic axum server setup Source: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html This is a basic setup for an axum server. It demonstrates how to create a router and start a listener. The handler function is initially synchronous, which will cause an error. ```rust use axum::{routing::get, Router}; #[tokio::main] async fn main() { let app = Router::new().route("/", get(handler)); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); } fn handler() -> &'static str { "Hello, world" } ``` -------------------------------- ### Serve with UnixListener and MakeService from Method Router (Unix) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `UnixListener` and a `MakeService` created from a method router (`get(handler)`). ```rust serve( UnixListener::bind("").unwrap(), get(handler).into_make_service(), ); ``` -------------------------------- ### GET / Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html This example shows how to route GET requests to a specific handler, while DELETE requests are routed to another handler. ```APIDOC ## GET / ### Description Handles GET requests to the root path. Additionally, DELETE requests to the root path are handled by a separate specific handler. ### Method GET, DELETE ### Endpoint / ### Parameters N/A ### Request Body N/A ### Request Example ```rust use axum::{ routing::get, Router, routing::MethodFilter }; async fn handler() {} async fn other_handler() {} // Requests to `GET /` will go to `handler` and `DELETE /` will go to // `other_handler` let app = Router::new().route("/", get(handler).delete(other_handler)); ``` ### Response (Not specified in the provided text) ### Response Example (Not specified in the provided text) ``` -------------------------------- ### Serve with UnixListener and Method Router (Unix) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving a specific handler using `get(handler)` with a `UnixListener`. ```rust serve(UnixListener::bind("").unwrap(), get(handler)); ``` -------------------------------- ### Serve with TcpListener and MakeService from Method Router Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `TcpListener` and a `MakeService` created from a method router (`get(handler)`). ```rust serve( TcpListener::bind(addr).await.unwrap(), get(handler).into_make_service(), ); ``` -------------------------------- ### Serve with TcpListener and Method Router Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving a specific handler using `get(handler)` with a `TcpListener`. ```rust serve(TcpListener::bind(addr).await.unwrap(), get(handler)); ``` -------------------------------- ### Serve with TcpListener and Method Router (TCP_NODELAY) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving a specific handler using `get(handler)` with a `TcpListener` and TCP_NODELAY enabled. ```rust serve(tcp_nodelay_listener().await, get(handler)); ``` -------------------------------- ### Serve with TcpListener and MakeService from Method Router (TCP_NODELAY) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `TcpListener` with TCP_NODELAY enabled and a `MakeService` created from a method router (`get(handler)`). ```rust serve( tcp_nodelay_listener().await, get(handler).into_make_service(), ); ``` -------------------------------- ### Basic Axum Server Setup Source: https://docs.rs/axum/latest/axum/attr.debug_handler.html A standard Axum server setup without the debug_handler macro, used to illustrate error generation. ```rust use axum::{routing::get, Router}; #[tokio::main] async fn main() { let app = Router::new().route("/", get(handler)); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); } fn handler() -> &'static str { "Hello, world" } ``` -------------------------------- ### Example Usage of TypedPath Source: https://docs.rs/axum-extra/latest/axum_extra/routing/trait.TypedPath.html Demonstrates how to use the `#[derive(TypedPath)]` macro to create type-safe routes for GET, POST, and DELETE requests. ```APIDOC ## Example ```rust use serde::Deserialize; use axum::{Router, extract::Json}; use axum_extra::routing::{ TypedPath, RouterExt, // for `Router::typed_*` }; // A type-safe route with `/users/{id}` as its associated path. #[derive(TypedPath, Deserialize)] #[typed_path("/users/{id}")] struct UsersMember { id: u32, } // A regular handler function that takes `UsersMember` as the first argument // and thus creates a typed connection between this handler and the `/users/{id}` path. // // The `TypedPath` must be the first argument to the function. async fn users_show( UsersMember { id }: UsersMember, ) { // ... } let app = Router::new() // Add our typed route to the router. // // The path will be inferred to `/users/{id}` since `users_show`'s // first argument is `UsersMember` which implements `TypedPath` .typed_get(users_show) .typed_post(users_create) .typed_delete(users_destroy); #[derive(TypedPath)] #[typed_path("/users")] struct UsersCollection; #[derive(Deserialize)] struct UsersCreatePayload { /* ... */ } async fn users_create( _: UsersCollection, // Our handlers can accept other extractors. Json(payload): Json, ) { // ... } async fn users_destroy(_: UsersCollection) { /* ... */ } ``` ``` -------------------------------- ### Serve with UnixListener and MakeService (Unix) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `UnixListener` and a `MakeService` from a `Router`. ```rust serve( UnixListener::bind("").unwrap(), router.clone().into_make_service(), ); ``` -------------------------------- ### Test Client Setup for Host Extractor Source: https://docs.rs/axum-extra/latest/src/axum_extra/extract/host.rs.html This setup demonstrates how to create a test client for the `Host` extractor. It defines a simple handler that returns the extracted host as a string and initializes a `TestClient` with a basic Axum router. ```rust use super::*; use crate::test_helpers::TestClient; use axum::{routing::get, Router}; use http::{header::HeaderName, Request}; fn test_client() -> TestClient { async fn host_as_body(Host(host): Host) -> String { host } TestClient::new(Router::new().route("/", get(host_as_body))) } ``` -------------------------------- ### Example: Using error_for_status_ref Source: https://docs.rs/axum/latest/axum/test_helpers/struct.TestResponse.html An example demonstrating how to use `error_for_status_ref` to check for and handle HTTP errors in a response. ```rust fn on_response(res: &Response) { match res.error_for_status_ref() { Ok(_res) => (), Err(err) => { // asserting a 400 as an example // it could be any status between 400...599 assert_eq!( err.status(), Some(reqwest::StatusCode::BAD_REQUEST) ); } } } ``` -------------------------------- ### Axum WebSocket Subprotocol Example Source: https://docs.rs/axum/latest/src/axum/extract/ws.rs.html Example demonstrating how to set preferred WebSocket subprotocols using the `protocols` method for a WebSocket upgrade handler. ```rust use axum::* let app = Router::new().route("/ws", any(handler)); async fn handler(ws: WebSocketUpgrade) -> Response { ws.protocols(["graphql-ws", "graphql-transport-ws"]) .on_upgrade(|socket| async { // ... }) } # let _: Router = app; ``` -------------------------------- ### Axum Router Setup with Redirect in Rust Source: https://docs.rs/axum/latest/src/axum/response/redirect.rs.html This example demonstrates how to configure an Axum router to use `Redirect` responses. It sets up a route `/old` that permanently redirects to `/new`, and a `/new` route that returns a simple string. ```rust use axum::{ routing::get, response::Redirect, Router, }; let app = Router::new() .route("/old", get(|| async { Redirect::permanent("/new") })) .route("/new", get(|| async { "Hello!" })); # let _: Router = app; ``` -------------------------------- ### Axum Multipart Upload Example Source: https://docs.rs/axum-extra/latest/src/axum_extra/extract/multipart.rs.html An example demonstrating how to handle multipart uploads in Axum. It iterates through fields and then through chunks of each field, printing the received byte count. ```rust use axum:: routing::post, response::IntoResponse, http::StatusCode, Router; use axum_extra::extract::Multipart; async fn upload(mut multipart: Multipart) -> Result<(), (StatusCode, String)> { while let Some(mut field) = multipart .next_field() .await .map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))? { while let Some(chunk) = field .chunk() .await .map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))? { println!("received {} bytes", chunk.len()); } } Ok(()) } let app = Router::new().route("/upload", post(upload)); # let _: Router = app; ``` -------------------------------- ### Route GET requests with get_service Source: https://docs.rs/axum/latest/axum/routing/method_routing/fn.get_service.html Demonstrates routing GET requests to a service created with tower::service_fn. ```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)); ``` -------------------------------- ### Test with MockConnectInfo Source: https://docs.rs/axum/latest/axum/extract/connect_info/struct.MockConnectInfo.html Example demonstrating how to apply MockConnectInfo as a layer to a router for testing purposes. ```rust 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); } ``` -------------------------------- ### Basic Axum "Hello, World!" Example Source: https://docs.rs/axum/latest/axum/index.html A minimal axum application that sets up a single route for "/" and listens on port 3000. Requires tokio's macros and rt-multi-thread features. ```rust 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(); } ``` -------------------------------- ### GET /uri/query Source: https://docs.rs/axum/latest/axum/extract/struct.OriginalUri.html Retrieves the query string component of a URI, which starts after the '?' character. ```APIDOC ## GET /uri/query ### Description Retrieves the query string component of the URI. ### Response #### Success Response (200) - **query** (Option<&str>) - The query string if present, otherwise None. ``` -------------------------------- ### Serve with UnixListener and MakeService with Connect Info (Unix) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `UnixListener` and a `MakeService` configured to provide custom Unix domain socket connection information. ```rust serve( UnixListener::bind("").unwrap(), router.into_make_service_with_connect_info::(), ); ``` -------------------------------- ### GET /users/{id} Source: https://docs.rs/axum/latest/src/axum/json.rs.html Example of using the Json type as a response to serialize a struct into a JSON response. ```APIDOC ## GET /users/{id} ### Description Serializes a User struct into a JSON response with the correct Content-Type header. ### Method GET ### Endpoint /users/{id} ### Parameters #### Path Parameters - **id** (Uuid) - Required - The unique identifier of the user ### Response #### Success Response (200) - **id** (Uuid) - User unique identifier - **username** (String) - User display name #### Response Example { "id": "550e8400-e29b-41d4-a716-446655440000", "username": "johndoe" } ``` -------------------------------- ### Serve with TcpListener and MakeService Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `TcpListener` and a `MakeService` created from a `Router`. This is useful when the service needs to be created per connection. ```rust serve( TcpListener::bind(addr).await.unwrap(), router.clone().into_make_service(), ); ``` -------------------------------- ### GET /users/{id} Source: https://docs.rs/axum-extra/latest/src/axum_extra/protobuf.rs.html Example of using the Protobuf wrapper as a response type to return a Protobuf message. ```APIDOC ## GET /users/{id} ### Description Returns a Protobuf encoded message as the response body. Automatically sets the Content-Type to application/octet-stream if not specified. ### Method GET ### Endpoint /users/{id} ### Parameters #### Path Parameters - **id** (String) - Required - The unique identifier of the user. ### Response #### Success Response (200) - **body** (Binary) - The encoded Protobuf message. ``` -------------------------------- ### WebSocketUpgrade Configuration Example Source: https://docs.rs/axum/latest/axum/extract/struct.WebSocketUpgrade.html Demonstrates how to configure WebSocketUpgrade with specific protocols. Use this when you need to negotiate specific subprotocols with the client. ```rust 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.protocols(["graphql-ws", "graphql-transport-ws"]) .on_upgrade(|socket| async { // ... }) } ``` -------------------------------- ### match_indices: Iterate over matches and their start indices Source: https://docs.rs/axum/latest/axum/extract/ws/struct.Utf8Bytes.html Use `match_indices` to get an iterator over all occurrences of a pattern within a string, along with the starting index of each match. Overlapping matches are handled by returning only the index of the first match. ```rust let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect(); assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]); ``` ```rust let v: Vec<_> = "1abcabc2".match_indices("abc").collect(); assert_eq!(v, [(1, "abc"), (4, "abc")]); ``` ```rust let v: Vec<_> = "ababa".match_indices("aba").collect(); assert_eq!(v, [(0, "aba")]); // only the first `aba` ``` -------------------------------- ### Serve with TcpListener and MakeService (TCP_NODELAY) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `TcpListener` with TCP_NODELAY enabled and a `MakeService` from a `Router`. ```rust serve( tcp_nodelay_listener().await, router.clone().into_make_service(), ); ``` -------------------------------- ### Serve with UnixListener and MakeService with Connect Info from Method Router (Unix) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `UnixListener` and a `MakeService` configured to provide custom Unix domain socket connection information to a handler. ```rust serve( UnixListener::bind("").unwrap(), get(handler).into_make_service_with_connect_info::(), ); ``` -------------------------------- ### Serve with TcpListener and MakeService with Connect Info Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `TcpListener` and a `MakeService` configured to provide connection information (SocketAddr) to the service. ```rust serve( TcpListener::bind(addr).await.unwrap(), router .clone() .into_make_service_with_connect_info::(), ); ``` -------------------------------- ### Serve with TcpListener and MakeService with Connect Info (TCP_NODELAY) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `TcpListener` with TCP_NODELAY enabled and a `MakeService` configured to provide connection information (SocketAddr). ```rust serve( tcp_nodelay_listener().await, router .clone() .into_make_service_with_connect_info::(), ); ``` -------------------------------- ### GET / (Task-Local State Example) Source: https://docs.rs/axum/latest/axum/index.html Demonstrates how to use tokio's task_local variables to share authentication state between middleware and IntoResponse implementations. ```APIDOC ## GET / ### Description An example endpoint demonstrating how to propagate user state from an authentication middleware to a response handler using task-local variables. ### Method GET ### Endpoint / ### Request Example GET / HTTP/1.1 Authorization: ### Response #### Success Response (200) - **body** (string) - The name of the authenticated user. ``` -------------------------------- ### Serve a MethodRouter with axum Source: https://docs.rs/axum/latest/axum/fn.serve.html This example demonstrates serving a `MethodRouter`. It requires `tokio` and either `http1` or `http2` features. ```rust use axum::routing::get; 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(); ``` -------------------------------- ### Route DELETE requests to a handler Source: https://docs.rs/axum/latest/axum/routing/method_routing/fn.delete.html Use this function to define a route that responds to DELETE HTTP requests. Refer to the `get` function for usage examples. ```rust pub fn delete(handler: H) -> MethodRouter where H: Handler, T: 'static, S: Clone + Send + Sync + 'static, ``` -------------------------------- ### Serve with TcpListener and MakeService with Connect Info from Method Router Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `TcpListener` and a `MakeService` configured to provide connection information (SocketAddr) to a handler. ```rust serve( TcpListener::bind(addr).await.unwrap(), get(handler).into_make_service_with_connect_info::(), ); ``` -------------------------------- ### Define POST Route with axum::routing::method_routing::post Source: https://docs.rs/axum/latest/axum/routing/method_routing/fn.post.html Use this function to route POST requests to a handler. Refer to the `get` function documentation for a usage example. ```rust pub fn post(handler: H) -> MethodRouter where H: Handler, T: 'static, S: Clone + Send + Sync + 'static, ``` -------------------------------- ### Create an Axum Router with Redirects Source: https://docs.rs/axum/latest/axum/response/struct.Redirect.html Example of setting up routes that return permanent redirects. Ensure the Redirect struct and Router are imported. ```rust use axum::{ routing::get, response::Redirect, Router, }; let app = Router::new() .route("/old", get(|| async { Redirect::permanent("/new") })) .route("/new", get(|| async { "Hello!" })); ``` -------------------------------- ### Route TRACE requests with axum::routing::method_routing::trace Source: https://docs.rs/axum/latest/axum/routing/method_routing/fn.trace.html Use this function to route HTTP TRACE requests to a specific handler. See the `get` function for usage examples. ```rust pub fn trace(handler: H) -> MethodRouter where H: Handler, T: 'static, S: Clone + Send + Sync + 'static, ``` -------------------------------- ### Test Client Setup Source: https://docs.rs/axum-extra/latest/src/axum_extra/extract/scheme.rs.html Sets up a test client with a simple Axum router that extracts the `Scheme` and returns it as a string. This is used for testing the `Scheme` extractor's behavior. ```rust fn test_client() -> TestClient { async fn scheme_as_body(Scheme(scheme): Scheme) -> String { scheme } TestClient::new(Router::new().route("/", get(scheme_as_body))) } ``` -------------------------------- ### Example Usage of TypedPath with axum Router Source: https://docs.rs/axum-extra/latest/axum_extra/routing/trait.TypedPath.html Demonstrates how to define typed routes for GET, POST, and DELETE requests using `#[derive(TypedPath)]` and `RouterExt`. Ensure `TypedPath` is the first argument to your handler functions. ```rust use serde::Deserialize; use axum::{Router, extract::Json}; use axum_extra::routing::{ TypedPath, RouterExt, // for `Router::typed_*` }; // A type safe route with `/users/{id}` as its associated path. #[derive(TypedPath, Deserialize)] #[typed_path("/users/{id}")] struct UsersMember { id: u32, } // A regular handler function that takes `UsersMember` as the first argument // and thus creates a typed connection between this handler and the `/users/{id}` path. // // The `TypedPath` must be the first argument to the function. async fn users_show( UsersMember { id }: UsersMember, ) { // ... } let app = Router::new() // Add our typed route to the router. // // The path will be inferred to `/users/{id}` since `users_show`'s // first argument is `UsersMember` which implements `TypedPath` .typed_get(users_show) .typed_post(users_create) .typed_delete(users_destroy); #[derive(TypedPath)] #[typed_path("/users")] struct UsersCollection; #[derive(Deserialize)] struct UsersCreatePayload { /* ... */ } async fn users_create( _: UsersCollection, // Our handlers can accept other extractors. Json(payload): Json, ) { // ... } async fn users_destroy(_: UsersCollection) { /* ... */ } ``` -------------------------------- ### Serve with UnixListener and Router (Unix) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving an Axum `Router` using a `UnixListener`. This is typically used for inter-process communication on Unix-like systems. ```rust serve(UnixListener::bind("").unwrap(), router.clone()); ``` -------------------------------- ### Basic TSR Route Setup Source: https://docs.rs/axum-extra/latest/src/axum_extra/routing/mod.rs.html Demonstrates setting up routes with `route_with_tsr` for basic path matching and redirects. Use this for simple endpoints where you want to enforce or redirect trailing slashes. ```rust let app = Router::new() .route_with_tsr("/foo", get(|| async {})) .route_with_tsr("/bar/", get(|| async {})); ``` -------------------------------- ### Build Complex Router with Layers and Fallback Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html Example of constructing a complex Axum router by chaining multiple methods like `get`, `post`, `put`, applying `route_layer`, merging services, and defining a fallback handler. ```rust let app = crate::Router::new().route( "/", // use the all the things 💣️ get(ok) .post(ok) .route_layer(ValidateRequestHeaderLayer::bearer("password")) .merge(delete_service(ServeDir::new("."))) .fallback(|| async { StatusCode::NOT_FOUND }) .put(ok) .layer(TimeoutLayer::with_status_code( StatusCode::REQUEST_TIMEOUT, Duration::from_secs(10), )) ); ``` -------------------------------- ### Serve with TcpListener and MakeService with Connect Info from Method Router (TCP_NODELAY) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving using a `TcpListener` with TCP_NODELAY enabled and a `MakeService` configured to provide connection information (SocketAddr) to a handler. ```rust serve( tcp_nodelay_listener().await, get(handler).into_make_service_with_connect_info::(), ); ``` -------------------------------- ### Serve Axum App with Connect Info Source: https://docs.rs/axum/latest/axum/struct.Router.html Use `into_make_service_with_connect_info` to enable extracting connection information, like client socket addresses, into request extensions. ```rust use axum::{ extract::ConnectInfo, routing::get, Router, }; use std::net::SocketAddr; let app = Router::new().route("/", get(handler)); async fn handler(ConnectInfo(addr): ConnectInfo) -> String { format!("Hello {{addr}}") } let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app.into_make_service_with_connect_info::()).await.unwrap(); ``` -------------------------------- ### Corrected axum server with async handler and debug_handler Source: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html This example shows a corrected axum server setup where the handler function is marked as `async` and decorated with `#[debug_handler]`. This resolves the compilation error and provides better error diagnostics. ```rust use axum::{routing::get, Router, debug_handler}; #[tokio::main] async fn main() { let app = Router::new().route("/", get(handler)); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap(); } #[debug_handler] async fn handler() -> &'static str { "Hello, world" } ``` -------------------------------- ### Extract Original Request URI in Axum Handler Source: https://docs.rs/axum/latest/src/axum/extract/original_uri.rs.html Use OriginalUri as an extractor in a handler to get the full, original request URI, even if the service is nested. This example shows how `uri` and `original_uri` differ within a nested route. ```rust use axum:: routing::get, Router, extract::OriginalUri, http::Uri let api_routes = Router::new() .route( "/users", get(|uri: Uri, OriginalUri(original_uri): OriginalUri| async { // `uri` is `/users` // `original_uri` is `/api/users` }), ); let app = Router::new().nest("/api", api_routes); # let _: Router = app; ``` -------------------------------- ### POST / Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html This example demonstrates how to route a POST request to a specific handler while other methods go to a default handler. ```APIDOC ## POST / ### Description Handles POST requests to the root path. All other HTTP methods will be handled by a fallback function. ### Method POST ### Endpoint / ### Request Body (Not specified in the provided text) ### Response (Not specified in the provided text) ### Request Example ```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)); ``` ### Response Example (Not specified in the provided text) ``` -------------------------------- ### Making Router into a Service with Connect Info (`into_make_service_with_connect_info`) Source: https://docs.rs/axum/latest/axum/struct.Router.html Explains how to use `into_make_service_with_connect_info` to create a `MakeService` that captures connection information, such as the client's remote address, and makes it available via request extensions. ```APIDOC ## Making Router into a Service with Connect Info (`into_make_service_with_connect_info`) ### Description Available on **crate feature `tokio`** only. Converts this router into a `MakeService` that stores connection information (`C`) in a request extension. This allows extracting details like the client's remote address. ### Method `into_make_service_with_connect_info` ### Parameters - **C** (Type Parameter): The type that implements `Connected` for storing connection information. ### Example (Extracting Socket Address) ```rust use axum::{ extract::ConnectInfo, routing::get, Router, }; use std::net::SocketAddr; let app = Router::new().route("/", get(handler)); async fn handler(ConnectInfo(addr): ConnectInfo) -> String { format!("Hello {addr}") } let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app.into_make_service_with_connect_info::()).await.unwrap(); ``` ### Example (Implementing Custom `Connected`) ```rust use axum::{ extract::connect_info::{ConnectInfo, Connected}, routing::get, serve::IncomingStream, Router, }; use tokio::net::TcpListener; let app = Router::new().route("/", get(handler)); async fn handler( ConnectInfo(my_connect_info): ConnectInfo, ) -> String { format!("Hello {my_connect_info:?}") } #[derive(Clone, Debug)] struct MyConnectInfo { // ... fields for connection info } impl Connected> for MyConnectInfo { fn connect_info(target: IncomingStream<'_, TcpListener>) -> Self { MyConnectInfo { /* ... */ } } } let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app.into_make_service_with_connect_info::()).await.unwrap(); ``` ``` -------------------------------- ### Route GET requests to a handler Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html Use the get function to route GET requests to an asynchronous handler function. GET routes will also handle HEAD requests by removing the response body. ```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; ``` -------------------------------- ### GET / Routing Source: https://docs.rs/axum/latest/axum/routing/method_routing/fn.get.html The get function routes GET requests to a specified handler. It also handles HEAD requests by stripping the response body. ```APIDOC ## GET / ### Description Routes GET requests to the provided handler. Note that this also handles HEAD requests automatically by removing the response body. ### Method GET ### Endpoint / ### Parameters - **handler** (Handler) - Required - The asynchronous function or closure to handle the request. ### Request Example ```rust use axum::{routing::get, Router}; async fn handler() {} let app = Router::new().route("/", get(handler)); ``` ``` -------------------------------- ### Response Examples Source: https://docs.rs/axum/latest/axum/response/type.Response.html Example usage of the Response type. ```APIDOC ##### §Examples ```rust let response = Response::builder().body("some string").unwrap(); let mapped_response: Response<&[u8]> = response.map(|b| { assert_eq!(b, "some string"); b.as_bytes() }); assert_eq!(mapped_response.body(), &"some string".as_bytes()); ``` ``` -------------------------------- ### Test ALLOW Header with GET and HEAD Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html Ensures the ALLOW header is 'GET,HEAD' when only GET and HEAD methods are registered and a PUT request is made. ```rust #[crate::test] async fn sets_allow_header_get_head() { let mut svc = MethodRouter::new().get(ok).head(ok); let (status, headers, _) = call(Method::PUT, &mut svc).await; assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED); assert_eq!(headers[ALLOW], "GET,HEAD"); } ``` -------------------------------- ### GET / (get_service) Source: https://docs.rs/axum/latest/axum/routing/method_routing/fn.get_service.html Routes GET requests to a provided Tower service. ```APIDOC ## GET / ### Description Routes GET requests to the given service. Note that GET routes will also be called for HEAD requests but will have the response body removed. ### Method GET ### Endpoint / ### Parameters #### Request Body - **svc** (T) - Required - A service that implements Service + Clone + Send + Sync + 'static. ### Request Example let service = tower::service_fn(|request: Request| async { Ok::<_, Infallible>(Response::new(Body::empty())) }); let app = Router::new().route("/", get_service(service)); ### Response #### Success Response (200) - **Response** (IntoResponse) - The response returned by the provided service. ``` -------------------------------- ### Chain Handler for GET Requests Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html Chains an additional handler that will only accept `GET` requests. Similar to `get_service`, `GET` routes also handle `HEAD` requests with the body removed. ```rust macro_rules! chained_handler_fn { ( $name:ident, GET ) => { chained_handler_fn!( /// Chain an additional handler that will only accept `GET` requests. /// /// # Example /// /// ```rust /// use axum::{routing::post, Router}; /// /// async fn handler() {} /// /// async fn other_handler() {} /// /// // Requests to `POST /` will go to `handler` and `GET /` will go to /// // `other_handler`. /// let app = Router::new().route("/", post(handler).get(other_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. $name, GET ); }; ( $name:ident, CONNECT ) => { chained_handler_fn!( /// Chain an additional handler that will only accept `CONNECT` requests. /// /// See [`MethodFilter::CONNECT`] for when you'd want to use this, /// and [`MethodRouter::get`] for an example. $name, CONNECT ); }; ( $name:ident, $method:ident ) => { chained_handler_fn!( ``` -------------------------------- ### Serve with TcpListener and Router Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Basic example of serving an Axum `Router` using a `TcpListener`. Ensure the listener is bound to an address. ```rust serve(TcpListener::bind(addr).await.unwrap(), router.clone()); ``` -------------------------------- ### Route GET requests to a service Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html Use get_service to route GET requests to a Tower service. Note that GET routes also handle HEAD requests by stripping the response body. ```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; ``` -------------------------------- ### Handler Implementation Example Source: https://docs.rs/axum/latest/src/axum/handler/mod.rs.html Example of implementing the `Handler` trait for a function that takes no arguments. ```APIDOC ## Handler Implementation for `FnOnce() -> Fut` ### Description This implementation handles functions that take no arguments and return a future. ### Method `call` ### Endpoint N/A (Trait implementation) ### Parameters N/A ### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) - **`Response`**: The result of the handler's future. ### Response Example N/A ``` -------------------------------- ### GET Service Source: https://docs.rs/axum/latest/axum/routing/method_routing/struct.MethodRouter.html Chains an additional service that will only accept `GET` requests. Note that `GET` routes will also be called for `HEAD` requests but will have the response body removed. Explicit `HEAD` routes should be added afterwards if needed. ```APIDOC ## GET /api/resource/{id} ### Description Retrieves a specific resource by its ID. ### Method GET ### Endpoint /api/resource/{id} #### Path Parameters - **id** (string) - Required - The unique identifier of the resource ### Response #### Success Response (200) - **data** (object) - The requested resource data #### Response Example ```json { "data": { "id": "123", "name": "Example Resource" } } ``` ``` -------------------------------- ### Serve with TcpListener and Router (TCP_NODELAY) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving an Axum `Router` using a `TcpListener` with TCP_NODELAY enabled. This can reduce latency by skipping the Nagle algorithm. ```rust let tcp_nodelay_listener = || async { TcpListener::bind(addr).await.unwrap().tap_io(|tcp_stream| { if let Err(err) = tcp_stream.set_nodelay(true) { eprintln!("failed to set TCP_NODELAY on incoming connection: {err:#}"); } }) }; serve(tcp_nodelay_listener().await, router.clone()) .await .unwrap(); ``` -------------------------------- ### Add GET Handler to MethodRouter Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html Shows how to register a handler function for the GET method on a `MethodRouter`. ```rust let mut svc = MethodRouter::new().get(ok); let (status, _, body) = call(Method::GET, &mut svc).await; assert_eq!(status, StatusCode::OK); assert_eq!(body, "ok"); ``` -------------------------------- ### TapIo Listener Extension Example Source: https://docs.rs/axum/latest/src/axum/serve/listener.rs.html Demonstrates how to use the `tap_io` method to apply a function to each incoming TCP stream before it's used by the Axum router. This is useful for setting socket options like TCP_NODELAY. ```rust let listener = tokio::net::TcpListener::bind("0.0.0.0:3000") .await .unwrap() .tap_io(|tcp_stream| { if let Err(err) = tcp_stream.set_nodelay(true) { trace!("failed to set TCP_NODELAY on incoming connection: {err:#}"); } }); axum::serve(listener, router).await.unwrap(); ``` -------------------------------- ### Chain Service for GET Requests Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html Chains an additional service that will only accept `GET` requests. Note that `GET` routes also handle `HEAD` requests with the body removed; explicit `HEAD` routes should be added afterwards if needed. ```rust macro_rules! chained_service_fn { ( $name:ident, GET ) => { chained_service_fn!( /// Chain an additional service that will only accept `GET` requests. /// /// # Example /// /// ```rust /// use axum::{ /// extract::Request, /// Router, /// routing::post_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())) /// }); /// /// // Requests to `POST /` will go to `service` and `GET /` will go to /// // `other_service`. /// let app = Router::new().route("/", post_service(service).get_service(other_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. $name, GET ); }; ( $name:ident, CONNECT ) => { chained_service_fn!( /// Chain an additional service that will only accept `CONNECT` requests. /// /// See [`MethodFilter::CONNECT`] for when you'd want to use this, /// and [`MethodRouter::get_service`] for an example. $name, CONNECT ); }; ( $name:ident, $method:ident ) => { chained_service_fn!( #[doc = concat!("Chain an additional service that will only accept `", stringify!($method),"` requests.")] /// /// See [`MethodRouter::get_service`] for an example. $name, $method ); }; ( $(#[$m:meta])+ $name:ident, $method:ident ) => { $(#[$m])+ #[track_caller] pub fn $name(self, svc: T) -> Self where T: Service + Clone + Send + Sync + 'static, T::Response: IntoResponse + 'static, T::Future: Send + 'static, { self.on_service(MethodFilter::$method, svc) } }; } ``` -------------------------------- ### Chaining GET and POST Handlers Source: https://docs.rs/axum/latest/axum/routing/method_routing/struct.MethodRouter.html Chains an additional handler that will only accept GET requests. Note that HEAD requests are also handled by GET routes but their response bodies are removed. Explicit HEAD routes should be added afterwards. ```rust use axum::{routing::post, Router}; async fn handler() {} async fn other_handler() {} // Requests to `POST /` will go to `handler` and `GET /` will go to // `other_handler`. let app = Router::new().route("/", post(handler).get(other_handler)); ``` -------------------------------- ### Implement IntoResponse for various types Source: https://docs.rs/axum/latest/src/axum/response/mod.rs.html Examples demonstrating how to return different combinations of status codes, headers, and bodies. ```rust // just needs to compile #[allow(dead_code)] fn impl_trait_result_works() { async fn impl_trait_ok() -> Result { Ok(()) } async fn impl_trait_err() -> Result<(), impl IntoResponse> { Err(()) } async fn impl_trait_both(uri: Uri) -> Result { if uri.path() == "/" { Ok(()) } else { Err(()) } } async fn impl_trait(uri: Uri) -> impl IntoResponse { if uri.path() == "/" { Ok(()) } else { Err(()) } } _ = Router::<()>::new() .route("/", get(impl_trait_ok)) .route("/", get(impl_trait_err)) .route("/", get(impl_trait_both)) .route("/", get(impl_trait)); } // just needs to compile #[allow(dead_code)] fn tuple_responses() { async fn status() -> impl IntoResponse { StatusCode::OK } async fn status_headermap() -> impl IntoResponse { (StatusCode::OK, HeaderMap::new()) } async fn status_header_array() -> impl IntoResponse { (StatusCode::OK, [("content-type", "text/plain")]) } async fn status_headermap_body() -> impl IntoResponse { (StatusCode::OK, HeaderMap::new(), String::new()) } async fn status_header_array_body() -> impl IntoResponse { ( StatusCode::OK, [("content-type", "text/plain")], String::new(), ) } async fn status_headermap_impl_into_response() -> impl IntoResponse { (StatusCode::OK, HeaderMap::new(), impl_into_response()) } async fn status_header_array_impl_into_response() -> impl IntoResponse { ( StatusCode::OK, [("content-type", "text/plain")], impl_into_response(), ) } fn impl_into_response() -> impl IntoResponse {} async fn status_header_array_extension_body() -> impl IntoResponse { ( StatusCode::OK, [("content-type", "text/plain")], Extension(1), String::new(), ) } ``` -------------------------------- ### Test Non-Overlapping HEAD and GET Handlers Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html Confirms that registering both HEAD and GET handlers on a MethodRouter is allowed. ```rust #[crate::test] async fn head_get_does_not_overlap() { let _: MethodRouter<()> = head(ok).get(ok); } ``` -------------------------------- ### Serve with TcpListener and Handler Service (TCP_NODELAY) Source: https://docs.rs/axum/latest/src/axum/serve/mod.rs.html Example of serving a handler directly converted into a service using a `TcpListener` with TCP_NODELAY enabled. ```rust serve(tcp_nodelay_listener().await, handler.into_service()); ``` -------------------------------- ### Test Non-Overlapping GET and HEAD Handlers Source: https://docs.rs/axum/latest/src/axum/routing/method_routing.rs.html Confirms that registering both GET and HEAD handlers on a MethodRouter is allowed. ```rust #[crate::test] async fn get_head_does_not_overlap() { let _: MethodRouter<()> = get(ok).head(ok); } ``` -------------------------------- ### Router Configuration with State Source: https://docs.rs/axum/latest/axum/struct.Router.html Demonstrates how to configure a Router with state, even if no state is explicitly needed, for potential performance benefits. Also notes that `into_make_service` and `into_make_service_with_connect_info` handle this automatically. ```APIDOC ## Router Configuration with State ### Description If you need a `Router` that implements `Service` but you don’t need any state, it is recommended to call `with_state(())` before serving requests. This can potentially improve performance and reduce allocations by allowing axum to update internal router components. Note that `Router::into_make_service` and `Router::into_make_service_with_connect_info` perform this optimization automatically. ### Method `with_state` ### Example ```rust use axum::Router; let app = Router::new() .route("/", axum::routing::get(|| async {{ /* ... */ }})) // even though we don't need any state, call `with_state(())` anyway .with_state(()); ``` ``` -------------------------------- ### SSE Handler Example Source: https://docs.rs/axum/latest/src/axum/response/sse.rs.html An example of an SSE handler function that returns a stream of events with keep-alive messages. ```APIDOC ## GET /sse ### Description Handles Server-Sent Events by returning a stream of messages. ### Method GET ### Endpoint /sse ### Parameters None ### Request Body None ### Request Example None ### Response #### Success Response (200) - **Content-Type**: `text/event-stream` - **Cache-Control**: `no-cache` - **Body**: A stream of SSE formatted events. #### Response Example ```rust use axum::response::sse::{Event, KeepAlive, Sse}; use std::{time::Duration, convert::Infallible}; use tokio_stream::StreamExt as _; use futures_util::stream::{self, Stream}; 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()) } ``` ```