Module axum::service [−][src]
Expand description
Use Tower Service
s to handle requests.
Most of the time applications will be written by composing
handlers, however sometimes you might have some general
Service
that you want to route requests to. That is enabled by the
functions in this module.
Example
Using Redirect
to redirect requests can be done like so:
use tower_http::services::Redirect;
use axum::{
body::Body,
handler::get,
http::Request,
Router,
service,
};
async fn handler(request: Request<Body>) { /* ... */ }
let redirect_service = Redirect::<Body>::permanent("/new".parse().unwrap());
let app = Router::new()
.route("/old", service::get(redirect_service))
.route("/new", get(handler));
Regarding backpressure and Service::poll_ready
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 wont 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 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:
use axum::{
handler::get,
Router,
};
use tower::ServiceBuilder;
async fn handler() { /* ... */ }
let app = Router::new().route("/", get(handler));
let app = ServiceBuilder::new()
.layer(some_backpressure_sensitive_middleware)
.service(app);
However when applying middleware around your whole application in this way you have to take care that errors are still being handled with 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.
Modules
Structs
A Service
adapter that handles errors with a closure.
A Service
that accepts requests based on a MethodFilter
and allows
chaining additional services.
Functions
Route requests to the given service regardless of the HTTP method.
Route CONNECT
requests to the given service.
Route DELETE
requests to the given service.
Route GET
requests to the given service.
Route HEAD
requests to the given service.
Route requests with the given method to the service.
Route OPTIONS
requests to the given service.
Route PATCH
requests to the given service.
Route POST
requests to the given service.
Route PUT
requests to the given service.
Route TRACE
requests to the given service.