diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index ba29cdaa2..7522545cf 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -1,7 +1,7 @@ # Changes ## Unreleased - 2021-xx-xx - +- Add `ServiceRequest::extract` to make it easier to use extractors when writing middlewares. ## 4.0.0-rc.3 - 2022-02-08 ### Changed diff --git a/actix-web/src/extract.rs b/actix-web/src/extract.rs index f16c29ca5..c0685cd4d 100644 --- a/actix-web/src/extract.rs +++ b/actix-web/src/extract.rs @@ -18,6 +18,9 @@ use crate::{dev::Payload, Error, HttpRequest}; /// A type that implements [`FromRequest`] is called an **extractor** and can extract data from /// the request. Some types that implement this trait are: [`Json`], [`Header`], and [`Path`]. /// +/// Check out [`ServiceRequest::extract`](crate::dev::ServiceRequest::extract) if you want to leverage +/// extractors when implementing middlewares. +/// /// # Configuration /// An extractor can be customized by injecting the corresponding configuration with one of: /// diff --git a/actix-web/src/service.rs b/actix-web/src/service.rs index 3843abcf8..00617d048 100644 --- a/actix-web/src/service.rs +++ b/actix-web/src/service.rs @@ -24,7 +24,7 @@ use crate::{ guard::{Guard, GuardContext}, info::ConnectionInfo, rmap::ResourceMap, - Error, HttpRequest, HttpResponse, + Error, HttpRequest, HttpResponse, FromRequest }; pub(crate) type BoxedHttpService = BoxService, Error>; @@ -95,6 +95,31 @@ impl ServiceRequest { (&mut self.req, &mut self.payload) } + /// Use an [extractor](crate::FromRequest) to build a type out of the incoming request. + /// + /// `extract` is particularly handy when you need to use an extractor inside + /// a middleware implementation. + /// + /// # Example + /// + /// ```rust + /// use actix_web::dev::{ServiceRequest, ServiceResponse}; + /// use actix_web::web::Path; + /// use actix_web::Error; + /// + /// fn f(service_request: ServiceRequest) -> Result { + /// let path: Path<(String, u32)> = service_request.extract()?; + /// // [...] + /// # todo!() + /// } + /// ``` + pub fn extract(&mut self) -> ::Future + where + T: FromRequest + { + T::from_request(&self.req, &mut self.payload) + } + /// Construct request from parts. pub fn from_parts(req: HttpRequest, payload: Payload) -> Self { #[cfg(debug_assertions)]