axum/handler/
mod.rs

1//! Async functions that can be used to handle requests.
2//!
3#![doc = include_str!("../docs/handlers_intro.md")]
4//!
5//! Some examples of handlers:
6//!
7//! ```rust
8//! use axum::{body::Bytes, http::StatusCode};
9//!
10//! // Handler that immediately returns an empty `200 OK` response.
11//! async fn unit_handler() {}
12//!
13//! // Handler that immediately returns a `200 OK` response with a plain text
14//! // body.
15//! async fn string_handler() -> String {
16//!     "Hello, World!".to_string()
17//! }
18//!
19//! // Handler that buffers the request body and returns it.
20//! //
21//! // This works because `Bytes` implements `FromRequest`
22//! // and therefore can be used as an extractor.
23//! //
24//! // `String` and `StatusCode` both implement `IntoResponse` and
25//! // therefore `Result<String, StatusCode>` also implements `IntoResponse`
26//! async fn echo(body: Bytes) -> Result<String, StatusCode> {
27//!     if let Ok(string) = String::from_utf8(body.to_vec()) {
28//!         Ok(string)
29//!     } else {
30//!         Err(StatusCode::BAD_REQUEST)
31//!     }
32//! }
33//! ```
34//!
35//! Instead of a direct `StatusCode`, it makes sense to use intermediate error type
36//! that can ultimately be converted to `Response`. This allows using `?` operator
37//! in handlers. See those examples:
38//!
39//! * [`anyhow-error-response`][anyhow] for generic boxed errors
40//! * [`error-handling`][error-handling] for application-specific detailed errors
41//!
42//! [anyhow]: https://github.com/tokio-rs/axum/blob/main/examples/anyhow-error-response/src/main.rs
43//! [error-handling]: https://github.com/tokio-rs/axum/blob/main/examples/error-handling/src/main.rs
44//!
45#![doc = include_str!("../docs/debugging_handler_type_errors.md")]
46
47#[cfg(feature = "tokio")]
48use crate::extract::connect_info::IntoMakeServiceWithConnectInfo;
49use crate::{
50    extract::{FromRequest, FromRequestParts, Request},
51    response::{IntoResponse, Response},
52    routing::IntoMakeService,
53};
54use std::{convert::Infallible, fmt, future::Future, marker::PhantomData, pin::Pin};
55use tower::ServiceExt;
56use tower_layer::Layer;
57use tower_service::Service;
58
59pub mod future;
60mod service;
61
62pub use self::service::HandlerService;
63
64/// Trait for async functions that can be used to handle requests.
65///
66/// You shouldn't need to depend on this trait directly. It is automatically
67/// implemented to closures of the right types.
68///
69/// See the [module docs](crate::handler) for more details.
70///
71/// # Converting `Handler`s into [`Service`]s
72///
73/// To convert `Handler`s into [`Service`]s you have to call either
74/// [`HandlerWithoutStateExt::into_service`] or [`Handler::with_state`]:
75///
76/// ```
77/// use tower::Service;
78/// use axum::{
79///     extract::{State, Request},
80///     body::Body,
81///     handler::{HandlerWithoutStateExt, Handler},
82/// };
83///
84/// // this handler doesn't require any state
85/// async fn one() {}
86/// // so it can be converted to a service with `HandlerWithoutStateExt::into_service`
87/// assert_service(one.into_service());
88///
89/// // this handler requires state
90/// async fn two(_: State<String>) {}
91/// // so we have to provide it
92/// let handler_with_state = two.with_state(String::new());
93/// // which gives us a `Service`
94/// assert_service(handler_with_state);
95///
96/// // helper to check that a value implements `Service`
97/// fn assert_service<S>(service: S)
98/// where
99///     S: Service<Request>,
100/// {}
101/// ```
102#[doc = include_str!("../docs/debugging_handler_type_errors.md")]
103///
104/// # Handlers that aren't functions
105///
106/// The `Handler` trait is also implemented for `T: IntoResponse`. That allows easily returning
107/// fixed data for routes:
108///
109/// ```
110/// use axum::{
111///     Router,
112///     routing::{get, post},
113///     Json,
114///     http::StatusCode,
115/// };
116/// use serde_json::json;
117///
118/// let app = Router::new()
119///     // respond with a fixed string
120///     .route("/", get("Hello, World!"))
121///     // or return some mock data
122///     .route("/users", post((
123///         StatusCode::CREATED,
124///         Json(json!({ "id": 1, "username": "alice" })),
125///     )));
126/// # let _: Router = app;
127/// ```
128#[rustversion::attr(
129    since(1.78),
130    diagnostic::on_unimplemented(
131        note = "Consider using `#[axum::debug_handler]` to improve the error message"
132    )
133)]
134pub trait Handler<T, S>: Clone + Send + Sized + 'static {
135    /// The type of future calling this handler returns.
136    type Future: Future<Output = Response> + Send + 'static;
137
138    /// Call the handler with the given request.
139    fn call(self, req: Request, state: S) -> Self::Future;
140
141    /// Apply a [`tower::Layer`] to the handler.
142    ///
143    /// All requests to the handler will be processed by the layer's
144    /// corresponding middleware.
145    ///
146    /// This can be used to add additional processing to a request for a single
147    /// handler.
148    ///
149    /// Note this differs from [`routing::Router::layer`](crate::routing::Router::layer)
150    /// which adds a middleware to a group of routes.
151    ///
152    /// If you're applying middleware that produces errors you have to handle the errors
153    /// so they're converted into responses. You can learn more about doing that
154    /// [here](crate::error_handling).
155    ///
156    /// # Example
157    ///
158    /// Adding the [`tower::limit::ConcurrencyLimit`] middleware to a handler
159    /// can be done like so:
160    ///
161    /// ```rust
162    /// use axum::{
163    ///     routing::get,
164    ///     handler::Handler,
165    ///     Router,
166    /// };
167    /// use tower::limit::{ConcurrencyLimitLayer, ConcurrencyLimit};
168    ///
169    /// async fn handler() { /* ... */ }
170    ///
171    /// let layered_handler = handler.layer(ConcurrencyLimitLayer::new(64));
172    /// let app = Router::new().route("/", get(layered_handler));
173    /// # let _: Router = app;
174    /// ```
175    fn layer<L>(self, layer: L) -> Layered<L, Self, T, S>
176    where
177        L: Layer<HandlerService<Self, T, S>> + Clone,
178        L::Service: Service<Request>,
179    {
180        Layered {
181            layer,
182            handler: self,
183            _marker: PhantomData,
184        }
185    }
186
187    /// Convert the handler into a [`Service`] by providing the state
188    fn with_state(self, state: S) -> HandlerService<Self, T, S> {
189        HandlerService::new(self, state)
190    }
191}
192
193impl<F, Fut, Res, S> Handler<((),), S> for F
194where
195    F: FnOnce() -> Fut + Clone + Send + 'static,
196    Fut: Future<Output = Res> + Send,
197    Res: IntoResponse,
198{
199    type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
200
201    fn call(self, _req: Request, _state: S) -> Self::Future {
202        Box::pin(async move { self().await.into_response() })
203    }
204}
205
206macro_rules! impl_handler {
207    (
208        [$($ty:ident),*], $last:ident
209    ) => {
210        #[allow(non_snake_case, unused_mut)]
211        impl<F, Fut, S, Res, M, $($ty,)* $last> Handler<(M, $($ty,)* $last,), S> for F
212        where
213            F: FnOnce($($ty,)* $last,) -> Fut + Clone + Send + 'static,
214            Fut: Future<Output = Res> + Send,
215            S: Send + Sync + 'static,
216            Res: IntoResponse,
217            $( $ty: FromRequestParts<S> + Send, )*
218            $last: FromRequest<S, M> + Send,
219        {
220            type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
221
222            fn call(self, req: Request, state: S) -> Self::Future {
223                Box::pin(async move {
224                    let (mut parts, body) = req.into_parts();
225                    let state = &state;
226
227                    $(
228                        let $ty = match $ty::from_request_parts(&mut parts, state).await {
229                            Ok(value) => value,
230                            Err(rejection) => return rejection.into_response(),
231                        };
232                    )*
233
234                    let req = Request::from_parts(parts, body);
235
236                    let $last = match $last::from_request(req, state).await {
237                        Ok(value) => value,
238                        Err(rejection) => return rejection.into_response(),
239                    };
240
241                    let res = self($($ty,)* $last,).await;
242
243                    res.into_response()
244                })
245            }
246        }
247    };
248}
249
250all_the_tuples!(impl_handler);
251
252mod private {
253    // Marker type for `impl<T: IntoResponse> Handler for T`
254    #[allow(missing_debug_implementations)]
255    pub enum IntoResponseHandler {}
256}
257
258impl<T, S> Handler<private::IntoResponseHandler, S> for T
259where
260    T: IntoResponse + Clone + Send + 'static,
261{
262    type Future = std::future::Ready<Response>;
263
264    fn call(self, _req: Request, _state: S) -> Self::Future {
265        std::future::ready(self.into_response())
266    }
267}
268
269/// A [`Service`] created from a [`Handler`] by applying a Tower middleware.
270///
271/// Created with [`Handler::layer`]. See that method for more details.
272pub struct Layered<L, H, T, S> {
273    layer: L,
274    handler: H,
275    _marker: PhantomData<fn() -> (T, S)>,
276}
277
278impl<L, H, T, S> fmt::Debug for Layered<L, H, T, S>
279where
280    L: fmt::Debug,
281{
282    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
283        f.debug_struct("Layered")
284            .field("layer", &self.layer)
285            .finish()
286    }
287}
288
289impl<L, H, T, S> Clone for Layered<L, H, T, S>
290where
291    L: Clone,
292    H: Clone,
293{
294    fn clone(&self) -> Self {
295        Self {
296            layer: self.layer.clone(),
297            handler: self.handler.clone(),
298            _marker: PhantomData,
299        }
300    }
301}
302
303impl<H, S, T, L> Handler<T, S> for Layered<L, H, T, S>
304where
305    L: Layer<HandlerService<H, T, S>> + Clone + Send + 'static,
306    H: Handler<T, S>,
307    L::Service: Service<Request, Error = Infallible> + Clone + Send + 'static,
308    <L::Service as Service<Request>>::Response: IntoResponse,
309    <L::Service as Service<Request>>::Future: Send,
310    T: 'static,
311    S: 'static,
312{
313    type Future = future::LayeredFuture<L::Service>;
314
315    fn call(self, req: Request, state: S) -> Self::Future {
316        use futures_util::future::{FutureExt, Map};
317
318        let svc = self.handler.with_state(state);
319        let svc = self.layer.layer(svc);
320
321        let future: Map<
322            _,
323            fn(
324                Result<
325                    <L::Service as Service<Request>>::Response,
326                    <L::Service as Service<Request>>::Error,
327                >,
328            ) -> _,
329        > = svc.oneshot(req).map(|result| match result {
330            Ok(res) => res.into_response(),
331            Err(err) => match err {},
332        });
333
334        future::LayeredFuture::new(future)
335    }
336}
337
338/// Extension trait for [`Handler`]s that don't have state.
339///
340/// This provides convenience methods to convert the [`Handler`] into a [`Service`] or [`MakeService`].
341///
342/// [`MakeService`]: tower::make::MakeService
343pub trait HandlerWithoutStateExt<T>: Handler<T, ()> {
344    /// Convert the handler into a [`Service`] and no state.
345    fn into_service(self) -> HandlerService<Self, T, ()>;
346
347    /// Convert the handler into a [`MakeService`] and no state.
348    ///
349    /// See [`HandlerService::into_make_service`] for more details.
350    ///
351    /// [`MakeService`]: tower::make::MakeService
352    fn into_make_service(self) -> IntoMakeService<HandlerService<Self, T, ()>>;
353
354    /// Convert the handler into a [`MakeService`] which stores information
355    /// about the incoming connection and has no state.
356    ///
357    /// See [`HandlerService::into_make_service_with_connect_info`] for more details.
358    ///
359    /// [`MakeService`]: tower::make::MakeService
360    #[cfg(feature = "tokio")]
361    fn into_make_service_with_connect_info<C>(
362        self,
363    ) -> IntoMakeServiceWithConnectInfo<HandlerService<Self, T, ()>, C>;
364}
365
366impl<H, T> HandlerWithoutStateExt<T> for H
367where
368    H: Handler<T, ()>,
369{
370    fn into_service(self) -> HandlerService<Self, T, ()> {
371        self.with_state(())
372    }
373
374    fn into_make_service(self) -> IntoMakeService<HandlerService<Self, T, ()>> {
375        self.into_service().into_make_service()
376    }
377
378    #[cfg(feature = "tokio")]
379    fn into_make_service_with_connect_info<C>(
380        self,
381    ) -> IntoMakeServiceWithConnectInfo<HandlerService<Self, T, ()>, C> {
382        self.into_service().into_make_service_with_connect_info()
383    }
384}
385
386#[cfg(test)]
387mod tests {
388    use super::*;
389    use crate::{extract::State, test_helpers::*};
390    use axum_core::body::Body;
391    use http::StatusCode;
392    use std::time::Duration;
393    use tower_http::{
394        limit::RequestBodyLimitLayer, map_request_body::MapRequestBodyLayer,
395        map_response_body::MapResponseBodyLayer, timeout::TimeoutLayer,
396    };
397
398    #[crate::test]
399    async fn handler_into_service() {
400        async fn handle(body: String) -> impl IntoResponse {
401            format!("you said: {body}")
402        }
403
404        let client = TestClient::new(handle.into_service());
405
406        let res = client.post("/").body("hi there!").await;
407        assert_eq!(res.status(), StatusCode::OK);
408        assert_eq!(res.text().await, "you said: hi there!");
409    }
410
411    #[crate::test]
412    async fn with_layer_that_changes_request_body_and_state() {
413        async fn handle(State(state): State<&'static str>) -> &'static str {
414            state
415        }
416
417        let svc = handle
418            .layer((
419                RequestBodyLimitLayer::new(1024),
420                TimeoutLayer::new(Duration::from_secs(10)),
421                MapResponseBodyLayer::new(Body::new),
422            ))
423            .layer(MapRequestBodyLayer::new(Body::new))
424            .with_state("foo");
425
426        let client = TestClient::new(svc);
427        let res = client.get("/").await;
428        assert_eq!(res.text().await, "foo");
429    }
430}