Module axum::service[][src]

Expand description

Use Tower Services 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::{service, handler, prelude::*};

async fn handler(request: Request<Body>) { /* ... */ }

let redirect_service = Redirect::<Body>::permanent("/new".parse().unwrap());

let app = route("/old", service::get(redirect_service))
    .route("/new", handler::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::prelude::*;
use tower::ServiceBuilder;

async fn handler() { /* ... */ }

let app = 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

Service future types.

Structs

A Service that boxes response bodies.

A Service adapter that handles errors with a closure.

A Service that accepts requests based on a MethodFilter and allows chaining additional services.

Traits

Extension trait that adds additional methods to Service.

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.