Add `ServiceRequest::extract`

This commit is contained in:
Luca P 2022-02-12 18:47:34 +00:00
parent 4c59a34513
commit fd8f5e712f
3 changed files with 30 additions and 2 deletions

View File

@ -1,7 +1,7 @@
# Changes # Changes
## Unreleased - 2021-xx-xx ## 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 ## 4.0.0-rc.3 - 2022-02-08
### Changed ### Changed

View File

@ -18,6 +18,9 @@ use crate::{dev::Payload, Error, HttpRequest};
/// A type that implements [`FromRequest`] is called an **extractor** and can extract data from /// 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`]. /// 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 /// # Configuration
/// An extractor can be customized by injecting the corresponding configuration with one of: /// An extractor can be customized by injecting the corresponding configuration with one of:
/// ///

View File

@ -24,7 +24,7 @@ use crate::{
guard::{Guard, GuardContext}, guard::{Guard, GuardContext},
info::ConnectionInfo, info::ConnectionInfo,
rmap::ResourceMap, rmap::ResourceMap,
Error, HttpRequest, HttpResponse, Error, HttpRequest, HttpResponse, FromRequest
}; };
pub(crate) type BoxedHttpService = BoxService<ServiceRequest, ServiceResponse<BoxBody>, Error>; pub(crate) type BoxedHttpService = BoxService<ServiceRequest, ServiceResponse<BoxBody>, Error>;
@ -95,6 +95,31 @@ impl ServiceRequest {
(&mut self.req, &mut self.payload) (&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<ServiceResponse, Error> {
/// let path: Path<(String, u32)> = service_request.extract()?;
/// // [...]
/// # todo!()
/// }
/// ```
pub fn extract<T>(&mut self) -> <T as FromRequest>::Future
where
T: FromRequest
{
T::from_request(&self.req, &mut self.payload)
}
/// Construct request from parts. /// Construct request from parts.
pub fn from_parts(req: HttpRequest, payload: Payload) -> Self { pub fn from_parts(req: HttpRequest, payload: Payload) -> Self {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]