Skip to main content
A Service that accepts requests based on a MethodFilter and allows chaining additional handlers and services. Whether or not MethodRouter implements Service depends on the state type it requires. A MethodRouter without required state (i.e., MethodRouter<()>) implements Service. If it requires state, you must call with_state() first.

Top-level handler functions

get
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route GET requests to the given handler.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 if needed.
use axum::{routing::get, Router};

async fn handler() -> &'static str {
    "Hello, World!"
}

let app = Router::new().route("/", get(handler));
post
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route POST requests to the given handler.
use axum::{routing::post, Router};

async fn create_user() -> &'static str {
    "User created"
}

let app = Router::new().route("/users", post(create_user));
put
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route PUT requests to the given handler.
use axum::{routing::put, Router};

async fn update_user() -> &'static str {
    "User updated"
}

let app = Router::new().route("/users/:id", put(update_user));
delete
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route DELETE requests to the given handler.
use axum::{routing::delete, Router};

async fn delete_user() -> &'static str {
    "User deleted"
}

let app = Router::new().route("/users/:id", delete(delete_user));
patch
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route PATCH requests to the given handler.
use axum::{routing::patch, Router};

async fn patch_user() -> &'static str {
    "User patched"
}

let app = Router::new().route("/users/:id", patch(patch_user));
head
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route HEAD requests to the given handler.
use axum::{routing::head, Router};

async fn head_handler() {}

let app = Router::new().route("/", head(head_handler));
options
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route OPTIONS requests to the given handler.
use axum::{routing::options, Router};

async fn options_handler() -> &'static str {
    "OPTIONS response"
}

let app = Router::new().route("/", options(options_handler));
trace
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route TRACE requests to the given handler.
use axum::{routing::trace, Router};

async fn trace_handler() {}

let app = Router::new().route("/", trace(trace_handler));
connect
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route CONNECT requests to the given handler.See MethodFilter::CONNECT for when you’d want to use this.
use axum::{routing::connect, Router};

async fn connect_handler() {}

let app = Router::new().route("/", connect(connect_handler));
on
fn<H, T, S>(filter: MethodFilter, handler: H) -> MethodRouter<S, Infallible>
Route requests with the given method filter to the handler.
use axum::{routing::{on, MethodFilter}, Router};

async fn handler() {}

let app = Router::new().route("/", on(MethodFilter::POST, handler));
any
fn<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
Route requests with any method to the given handler.Additional methods can still be chained to override specific methods.
use axum::{routing::any, Router};

async fn handler() -> &'static str {
    "Handles all methods"
}

async fn post_handler() -> &'static str {
    "Handles POST specifically"
}

// POST goes to post_handler, all other methods go to handler
let app = Router::new().route("/", any(handler).post(post_handler));

Top-level service functions

get_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route GET requests to the given service.Note that get routes will also be called for HEAD requests but will have the response body removed.
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()))
});

let app = Router::new().route("/", get_service(service));
post_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route POST requests to the given service.See get_service for an example.
put_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route PUT requests to the given service.See get_service for an example.
delete_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route DELETE requests to the given service.See get_service for an example.
patch_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route PATCH requests to the given service.See get_service for an example.
head_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route HEAD requests to the given service.See get_service for an example.
options_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route OPTIONS requests to the given service.See get_service for an example.
trace_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route TRACE requests to the given service.See get_service for an example.
connect_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route CONNECT requests to the given service.See MethodFilter::CONNECT for when you’d want to use this, and get_service for an example.
on_service
fn<T, S>(filter: MethodFilter, svc: T) -> MethodRouter<S, T::Error>
Route requests with the given method to the service.
use axum::{
    extract::Request,
    routing::on_service,
    Router,
    body::Body,
    routing::MethodFilter,
};
use http::Response;
use std::convert::Infallible;

let service = tower::service_fn(|request: Request| async {
    Ok::<_, Infallible>(Response::new(Body::empty()))
});

let app = Router::new().route("/", on_service(MethodFilter::POST, service));
any_service
fn<T, S>(svc: T) -> MethodRouter<S, T::Error>
Route requests to the given service regardless of method.Additional methods can still be chained to override specific methods.
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));

MethodRouter instance methods

MethodRouter::new
fn() -> Self
Create a default MethodRouter that will respond with 405 Method Not Allowed to all requests.
use axum::routing::MethodRouter;

let method_router = MethodRouter::new();
on
fn<H, T>(self, filter: MethodFilter, handler: H) -> Self
Chain an additional handler that will accept requests matching the given MethodFilter.
use axum::{routing::get, Router, routing::MethodFilter};

async fn handler() {}
async fn other_handler() {}

let app = Router::new()
    .route("/", get(handler).on(MethodFilter::DELETE, other_handler));
get
fn<H, T>(self, handler: H) -> Self
Chain an additional handler that will only accept GET requests.Note that get routes will also be called for HEAD requests but will have the response body removed.
use axum::{routing::post, Router};

async fn handler() {}
async fn other_handler() {}

let app = Router::new()
    .route("/", post(handler).get(other_handler));
post
fn<H, T>(self, handler: H) -> Self
Chain an additional handler that will only accept POST requests.See MethodRouter::get for an example.
put
fn<H, T>(self, handler: H) -> Self
Chain an additional handler that will only accept PUT requests.See MethodRouter::get for an example.
delete
fn<H, T>(self, handler: H) -> Self
Chain an additional handler that will only accept DELETE requests.See MethodRouter::get for an example.
patch
fn<H, T>(self, handler: H) -> Self
Chain an additional handler that will only accept PATCH requests.See MethodRouter::get for an example.
head
fn<H, T>(self, handler: H) -> Self
Chain an additional handler that will only accept HEAD requests.See MethodRouter::get for an example.
options
fn<H, T>(self, handler: H) -> Self
Chain an additional handler that will only accept OPTIONS requests.See MethodRouter::get for an example.
trace
fn<H, T>(self, handler: H) -> Self
Chain an additional handler that will only accept TRACE requests.See MethodRouter::get for an example.
connect
fn<H, T>(self, handler: H) -> Self
Chain an additional handler that will only accept CONNECT requests.See MethodRouter::get for an example.
on_service
fn<T>(self, filter: MethodFilter, svc: T) -> Self
Chain an additional service that will accept requests matching the given MethodFilter.
use axum::{
    extract::Request,
    Router,
    routing::{MethodFilter, on_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 app = Router::new().route("/", on_service(MethodFilter::DELETE, service));
get_service
fn<T>(self, svc: T) -> Self
Chain an additional service that will only accept GET requests.
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()))
});

let app = Router::new()
    .route("/", post_service(service).get_service(other_service));
post_service
fn<T>(self, svc: T) -> Self
Chain an additional service that will only accept POST requests.See MethodRouter::get_service for an example.
put_service
fn<T>(self, svc: T) -> Self
Chain an additional service that will only accept PUT requests.See MethodRouter::get_service for an example.
delete_service
fn<T>(self, svc: T) -> Self
Chain an additional service that will only accept DELETE requests.See MethodRouter::get_service for an example.
patch_service
fn<T>(self, svc: T) -> Self
Chain an additional service that will only accept PATCH requests.See MethodRouter::get_service for an example.
head_service
fn<T>(self, svc: T) -> Self
Chain an additional service that will only accept HEAD requests.See MethodRouter::get_service for an example.
options_service
fn<T>(self, svc: T) -> Self
Chain an additional service that will only accept OPTIONS requests.See MethodRouter::get_service for an example.
trace_service
fn<T>(self, svc: T) -> Self
Chain an additional service that will only accept TRACE requests.See MethodRouter::get_service for an example.
connect_service
fn<T>(self, svc: T) -> Self
Chain an additional service that will only accept CONNECT requests.See MethodRouter::get_service for an example.
fallback
fn<H, T>(self, handler: H) -> Self
Add a fallback handler to the method router.This handler is called when the request method doesn’t match any of the configured methods.
use axum::{routing::get, Router, http::StatusCode};

async fn get_handler() -> &'static str {
    "GET request"
}

async fn fallback_handler() -> (StatusCode, &'static str) {
    (StatusCode::METHOD_NOT_ALLOWED, "Method not allowed")
}

let app = Router::new()
    .route("/", get(get_handler).fallback(fallback_handler));
fallback_service
fn<T>(self, svc: T) -> Self
Add a fallback service to the method router.Like fallback but accepts a Service instead of a handler.
use axum::{extract::Request, routing::get, Router, body::Body};
use http::Response;
use std::convert::Infallible;

let fallback_service = tower::service_fn(|_: Request| async {
    Ok::<_, Infallible>(Response::new(Body::from("Fallback")))
});

let app = Router::new()
    .route("/", get(|| async { "GET" }).fallback_service(fallback_service));
layer
fn<L>(self, layer: L) -> MethodRouter<S, NewError>
Apply a tower::Layer to the method router.The layer is applied to all methods including the fallback.
use axum::{routing::get, Router};
use tower_http::trace::TraceLayer;

let app = Router::new()
    .route("/", get(|| async { "Hello" }).layer(TraceLayer::new_for_http()));
route_layer
fn<L>(self, layer: L) -> Self
Apply a tower::Layer to the method router’s routes, but not the fallback.This is useful when you want middleware to only apply to specific HTTP methods.
use axum::{routing::get, Router};
use tower_http::compression::CompressionLayer;

let app = Router::new()
    .route("/", 
        get(|| async { "data" })
            .route_layer(CompressionLayer::new())
            .fallback(|| async { "Not allowed" })
    );
merge
fn(self, other: Self) -> Self
Merge two method routers into one.This allows combining different method handlers. Both routers cannot have a custom fallback.
use axum::{routing::{get, post}, Router};

let get_route = get(|| async { "GET" });
let post_route = post(|| async { "POST" });

let app = Router::new()
    .route("/", get_route.merge(post_route));
with_state
fn<S2>(self, state: S) -> MethodRouter<S2, E>
Provide the state for the method router.This converts a MethodRouter<S> into a MethodRouter<()> that can be used as a service.
use axum::{routing::get, extract::State};

#[derive(Clone)]
struct AppState {
    count: u32,
}

let method_router = get(|State(state): State<AppState>| async move {
    format!("Count: {}", state.count)
}).with_state(AppState { count: 0 });
handle_error
fn<F, T>(self, f: F) -> MethodRouter<S, Infallible>
Apply a HandleErrorLayer.This is a convenience method for self.layer(HandleErrorLayer::new(f)).
use axum::{routing::get, Router, http::StatusCode};

async fn handler() -> Result<&'static str, std::io::Error> {
    Ok("Hello")
}

let app = Router::new()
    .route("/", 
        get(handler).handle_error(|_err| async {
            (StatusCode::INTERNAL_SERVER_ERROR, "Something went wrong")
        })
    );
method_filter
fn(&self) -> Option<MethodFilter>
Get a MethodFilter for the methods that this MethodRouter has custom code for.Returns None if the MethodRouter was constructed with any or has had a fallback set.
use axum::routing::{get, post, MethodFilter};

let method_router = get(|| async {}).post(|| async {});
let filter = method_router.method_filter();
assert_eq!(filter, Some(MethodFilter::GET | MethodFilter::POST));
into_make_service
fn(self) -> IntoMakeService<Self>
Convert the method router into a MakeService.This allows you to serve a single MethodRouter without path-based routing.Only available for MethodRouter<(), Infallible>.
use axum::routing::get;

let router = get(|| async { "GET" })
    .post(|| async { "POST" });

# async {
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, router.into_make_service()).await;
# };
into_make_service_with_connect_info
fn<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C>
Convert the method router into a MakeService which stores connection information.Requires the tokio feature. Only available for MethodRouter<(), Infallible>.
use axum::{routing::get, extract::ConnectInfo};
use std::net::SocketAddr;

async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
    format!("Hello {addr}")
}

let router = get(handler).post(handler);

# async {
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, router.into_make_service_with_connect_info::<SocketAddr>()).await;
# };