Skip to main content

Application

Trait Application 

Source
pub trait Application {
    // Required method
    fn execute(
        &self,
        request: &Request,
        connection: &ConnectionInfo,
    ) -> Result<Response, String>;

    // Provided methods
    fn runs_inline(
        &self,
        _request: &Request,
        _connection: &ConnectionInfo,
    ) -> bool { ... }
    fn execute_async<'a>(
        &'a self,
        _request: &'a Request,
        _connection: &'a ConnectionInfo,
    ) -> Option<Pin<Box<dyn Future<Output = Result<Response, String>> + Send + 'a>>> { ... }
    fn streams_body(
        &self,
        _request: &Request,
        _connection: &ConnectionInfo,
    ) -> bool { ... }
    fn registered_routes(&self) -> Vec<RouteInfo> { ... }
    fn middleware_names(&self) -> Vec<&'static str> { ... }
}
Expand description

Dispatch trait that wires controllers into a request-handling loop.

Implement this to define which controllers run and in what order. Pass the implementation to [Server::run] or [Server::run_tls].

The built-in App implementation covers static files, favicons, forms, and file uploads. Embed it or replace it entirely.

Required Methods§

Source

fn execute( &self, request: &Request, connection: &ConnectionInfo, ) -> Result<Response, String>

Receives a parsed request and returns a fully-built response. Walk your controller list with is_matching / process and return the first match.

Provided Methods§

Source

fn runs_inline(&self, _request: &Request, _connection: &ConnectionInfo) -> bool

true when executing request is quick and never waits on anything but the local filesystem — health checks, metrics, small static files. The async servers (HTTP/1.1, HTTP/2, HTTP/3) then call execute directly on the event loop, as nginx does, instead of handing the request to tokio’s blocking pool: that handoff (a shared lock and two cross-thread wake-ups) costs more than serving a small file.

Default false, and it must stay false for anything that can wait: a database query, an upstream request, a lock held across I/O. Run on the event loop, those would stall every other connection on that worker. Wrappers answer true only when every layer agrees.

Source

fn execute_async<'a>( &'a self, _request: &'a Request, _connection: &'a ConnectionInfo, ) -> Option<Pin<Box<dyn Future<Output = Result<Response, String>> + Send + 'a>>>

Available on crate feature http2 only.

An asynchronous version of execute for this request, when the application has one: the async servers await it on the connection’s task instead of tying up a blocking-pool thread while it waits (the config-driven proxy uses this to wait for a backend without holding a thread). None (the default) means “use execute”. Wrappers return Some only when they add no synchronous work of their own.

Source

fn streams_body(&self, _request: &Request, _connection: &ConnectionInfo) -> bool

true to receive this request’s body as a stream (Body::Stream) instead of read into memory first: execute then runs while the body is still arriving, on a blocking-pool thread, and reads it with std::io::Read — a multi-gigabyte upload in a few chunks of memory. Asked after the head is read, so request.body is empty here; decide from the method, path and headers.

Default false: the body is read first, as always. Async HTTP/1.1 and HTTP/2 honour it (HTTP/2 credits the stream’s window back as the handler reads); the HTTP/1.1-only build and HTTP/3 read the body first regardless. Wrappers answer true only when every layer leaves the body alone (Middleware::accepts_streamed_body).

Source

fn registered_routes(&self) -> Vec<RouteInfo>

The routes this application registers, as (method, pattern) — what AppWithState::route_entries returns; wrappers (WithMiddleware, McpServer) report the routes of the application inside. For tools that describe an app (the dev MCP server’s routes tool), not for dispatch. Default: none. Since 18.28.0.

Source

fn middleware_names(&self) -> Vec<&'static str>

The names of the middleware layers around this application’s routes, in the order a request passes them (Middleware::layer_name). Default: none; WithMiddleware lists its layers, then the inner application’s. Since 18.28.0.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl Application for A2aServer

Source§

impl Application for AdminApi

Source§

impl Application for App

Source§

impl Application for ConfigDrivenApp

Source§

impl Application for FastCgi

Source§

impl Application for IngressRouter

Source§

impl Application for LlmProxy

Source§

impl Application for McpServer

Source§

impl Application for PortRouter

Source§

impl<A> Application for DevMcp<A>
where A: Application,

Source§

impl<A> Application for TimeoutLayer<A>
where A: Application + Send + Sync + 'static + ?Sized,

Source§

impl<A> Application for WithMiddleware<A>
where A: Application,

Source§

impl<S, B, A> Application for Mount<S, A>
where S: Service<Request<Body>, Response = Response<B>> + Clone + Send + Sync + 'static, <S as Service<Request<Body>>>::Future: Send + 'static, <S as Service<Request<Body>>>::Error: Into<Box<dyn Error + Send + Sync>>, B: Body<Data = Bytes> + Send + 'static, <B as Body>::Error: Into<Box<dyn Error + Send + Sync>>, A: Application,

Source§

impl<S, B> Application for TowerApp<S>
where S: Service<Request<Body>, Response = Response<B>> + Clone + Send + Sync + 'static, <S as Service<Request<Body>>>::Future: Send + 'static, <S as Service<Request<Body>>>::Error: Into<Box<dyn Error + Send + Sync>>, B: Body<Data = Bytes> + Send + 'static, <B as Body>::Error: Into<Box<dyn Error + Send + Sync>>,

Source§

impl<S> Application for AppWithState<S>
where S: Send + Sync + 'static,

Source§

impl<S> Application for AsyncAppWithState<S>
where S: Send + Sync + 'static,