From a3a32f493e9ea9aba8b4f67b28ca542c1059b89a Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Sun, 8 May 2022 19:48:48 +0200 Subject: [PATCH] Add `MethodRouter::{into_make_service, into_make_service_with_connect_info}` (#1010) --- axum/CHANGELOG.md | 2 + axum/src/routing/method_routing.rs | 74 ++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md index ccd49bb9..a2316633 100644 --- a/axum/CHANGELOG.md +++ b/axum/CHANGELOG.md @@ -12,8 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 the request body will not be checked. If they do have a `Content-Length` header they'll be rejected. This allows `ContentLengthLimit` to be used as middleware around several routes, including `GET` routes ([#989]) +- **added:** Add `MethodRouter::{into_make_service, into_make_service_with_connect_info}` ([#1010]) [#989]: https://github.com/tokio-rs/axum/pull/989 +[#1010]: https://github.com/tokio-rs/axum/pull/1010 # 0.5.4 (26. April, 2022) diff --git a/axum/src/routing/method_routing.rs b/axum/src/routing/method_routing.rs index 06476dd0..edd3ac3a 100644 --- a/axum/src/routing/method_routing.rs +++ b/axum/src/routing/method_routing.rs @@ -1,10 +1,12 @@ +use super::IntoMakeService; use crate::{ body::{boxed, Body, Bytes, Empty, HttpBody}, error_handling::{HandleError, HandleErrorLayer}, + extract::connect_info::IntoMakeServiceWithConnectInfo, handler::Handler, http::{Method, Request, StatusCode}, response::Response, - routing::{Fallback, MethodFilter, Route}, + routing::{future::RouteFuture, Fallback, MethodFilter, Route}, BoxError, }; use bytes::BytesMut; @@ -586,6 +588,74 @@ where chained_handler_fn!(post, POST); chained_handler_fn!(put, PUT); chained_handler_fn!(trace, TRACE); + + /// Convert the handler into a [`MakeService`]. + /// + /// This allows you to serve a single handler if you don't need any routing: + /// + /// ```rust + /// use axum::{ + /// Server, + /// handler::Handler, + /// http::{Uri, Method}, + /// response::IntoResponse, + /// routing::get, + /// }; + /// use std::net::SocketAddr; + /// + /// async fn handler(method: Method, uri: Uri, body: String) -> impl IntoResponse { + /// format!("received `{} {}` with body `{:?}`", method, uri, body) + /// } + /// + /// let router = get(handler).post(handler); + /// + /// # async { + /// Server::bind(&SocketAddr::from(([127, 0, 0, 1], 3000))) + /// .serve(router.into_make_service()) + /// .await?; + /// # Ok::<_, hyper::Error>(()) + /// # }; + /// ``` + /// + /// [`MakeService`]: tower::make::MakeService + pub fn into_make_service(self) -> IntoMakeService { + IntoMakeService::new(self) + } + + /// Convert the router into a [`MakeService`] which stores information + /// about the incoming connection. + /// + /// See [`Router::into_make_service_with_connect_info`] for more details. + /// + /// ```rust + /// use axum::{ + /// Server, + /// handler::Handler, + /// response::IntoResponse, + /// extract::ConnectInfo, + /// routing::get, + /// }; + /// use std::net::SocketAddr; + /// + /// async fn handler(ConnectInfo(addr): ConnectInfo) -> impl IntoResponse { + /// format!("Hello {}", addr) + /// } + /// + /// let router = get(handler).post(handler); + /// + /// # async { + /// Server::bind(&SocketAddr::from(([127, 0, 0, 1], 3000))) + /// .serve(router.into_make_service_with_connect_info::()) + /// .await?; + /// # Ok::<_, hyper::Error>(()) + /// # }; + /// ``` + /// + /// [`MakeService`]: tower::make::MakeService + /// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info + pub fn into_make_service_with_connect_info(self) -> IntoMakeServiceWithConnectInfo { + IntoMakeServiceWithConnectInfo::new(self) + } } impl MethodRouter { @@ -958,8 +1028,6 @@ where } } -use crate::routing::future::RouteFuture; - impl Service> for MethodRouter where B: HttpBody,