From fd8f5e712f68056e924c8bb52810653e76b474db Mon Sep 17 00:00:00 2001 From: Luca P Date: Sat, 12 Feb 2022 18:47:34 +0000 Subject: [PATCH 1/4] Add `ServiceRequest::extract` --- actix-web/CHANGES.md | 2 +- actix-web/src/extract.rs | 3 +++ actix-web/src/service.rs | 27 ++++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index ba29cdaa2d0..7522545cf20 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 f16c29ca539..c0685cd4d48 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 3843abcf8ff..00617d04896 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)] From e081f6736e3b9334a882c7b41154f2bcfb76b1b0 Mon Sep 17 00:00:00 2001 From: Luca P Date: Sat, 12 Feb 2022 18:51:42 +0000 Subject: [PATCH 2/4] Fmt --- actix-web/src/extract.rs | 2 +- actix-web/src/service.rs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/actix-web/src/extract.rs b/actix-web/src/extract.rs index c0685cd4d48..65f8cf30cec 100644 --- a/actix-web/src/extract.rs +++ b/actix-web/src/extract.rs @@ -18,7 +18,7 @@ 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 +/// Check out [`ServiceRequest::extract`](crate::dev::ServiceRequest::extract) if you want to leverage /// extractors when implementing middlewares. /// /// # Configuration diff --git a/actix-web/src/service.rs b/actix-web/src/service.rs index 00617d04896..57771d4b5dd 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, FromRequest + Error, FromRequest, HttpRequest, HttpResponse, }; pub(crate) type BoxedHttpService = BoxService, Error>; @@ -96,17 +96,17 @@ impl ServiceRequest { } /// 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 + /// + /// `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()?; /// // [...] @@ -114,8 +114,8 @@ impl ServiceRequest { /// } /// ``` pub fn extract(&mut self) -> ::Future - where - T: FromRequest + where + T: FromRequest, { T::from_request(&self.req, &mut self.payload) } From 9c3ea3480ad7a105961037a8bb6c684da3cb68c7 Mon Sep 17 00:00:00 2001 From: Luca P Date: Sun, 13 Feb 2022 10:51:16 +0000 Subject: [PATCH 3/4] Fix doc example --- actix-web/src/service.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actix-web/src/service.rs b/actix-web/src/service.rs index 57771d4b5dd..7bdf04bfd3b 100644 --- a/actix-web/src/service.rs +++ b/actix-web/src/service.rs @@ -107,8 +107,8 @@ impl ServiceRequest { /// use actix_web::web::Path; /// use actix_web::Error; /// - /// fn f(service_request: ServiceRequest) -> Result { - /// let path: Path<(String, u32)> = service_request.extract()?; + /// async fn f(mut service_request: ServiceRequest) -> Result { + /// let path = service_request.extract::>().await?; /// // [...] /// # todo!() /// } From 95cff76f5ebda99b25dc68d1b3273211e7e055bb Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 28 Mar 2022 22:59:11 +0100 Subject: [PATCH 4/4] tweak docs --- actix-web/CHANGES.md | 5 ++++- actix-web/src/extract.rs | 5 ++--- actix-web/src/service.rs | 22 +++++++++++----------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 22aabca7e8b..06ab75871a5 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -1,7 +1,10 @@ # Changelog ## Unreleased - 2021-xx-xx -- Add `ServiceRequest::extract` to make it easier to use extractors when writing middlewares. +- Add `ServiceRequest::extract` to make it easier to use extractors when writing middlewares. [#2647] + +[#2647]: https://github.com/actix/actix-web/pull/2647 + ## 4.0.1 - 2022-02-25 ### Fixed diff --git a/actix-web/src/extract.rs b/actix-web/src/extract.rs index df17a669096..1b2f0bd197c 100644 --- a/actix-web/src/extract.rs +++ b/actix-web/src/extract.rs @@ -18,12 +18,11 @@ 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. +/// 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: -/// /// - [`App::app_data()`][crate::App::app_data] /// - [`Scope::app_data()`][crate::Scope::app_data] /// - [`Resource::app_data()`][crate::Resource::app_data] diff --git a/actix-web/src/service.rs b/actix-web/src/service.rs index 7bdf04bfd3b..589d8d77d98 100644 --- a/actix-web/src/service.rs +++ b/actix-web/src/service.rs @@ -95,20 +95,20 @@ impl ServiceRequest { (&mut self.req, &mut self.payload) } - /// Use an [extractor](crate::FromRequest) to build a type out of the incoming request. + /// Derives a type from this request using an [extractor](crate::FromRequest). /// - /// `extract` is particularly handy when you need to use an extractor inside - /// a middleware implementation. + /// Returns the `T` extractor's `Future` type which can be `await`ed. This is particularly handy + /// when you want to use an extractor in a middleware implementation. /// - /// # Example - /// - /// ```rust - /// use actix_web::dev::{ServiceRequest, ServiceResponse}; - /// use actix_web::web::Path; - /// use actix_web::Error; + /// # Examples + /// ``` + /// use actix_web::{ + /// dev::{ServiceRequest, ServiceResponse}, + /// web::Path, Error + /// }; /// - /// async fn f(mut service_request: ServiceRequest) -> Result { - /// let path = service_request.extract::>().await?; + /// async fn my_helper(mut srv_req: ServiceRequest) -> Result { + /// let path = srv_req.extract::>().await?; /// // [...] /// # todo!() /// }