mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-30 18:34:36 +01:00
remove Path and Query from public api
This commit is contained in:
parent
052d5f0bc5
commit
8fff2c7595
@ -2,6 +2,8 @@
|
||||
|
||||
## 0.4.11
|
||||
|
||||
* Added `HttpReuqest::extract_xxx()`, type safe path/query information extractor.
|
||||
|
||||
* Fix long client urls #129
|
||||
|
||||
* Fix panic on invalid URL characters #130
|
||||
|
@ -5,7 +5,7 @@ and [`ResponseError` trait](../actix_web/error/trait.ResponseError.html)
|
||||
for handling handler's errors.
|
||||
Any error that implements `ResponseError` trait can be returned as error value.
|
||||
*Handler* can return *Result* object, actix by default provides
|
||||
`Responder` implementation for compatible result object. Here is implementation
|
||||
`Responder` implementation for compatible result types. Here is implementation
|
||||
definition:
|
||||
|
||||
```rust,ignore
|
||||
@ -64,7 +64,7 @@ fn index(req: HttpRequest) -> Result<&'static str, MyError> {
|
||||
# }
|
||||
```
|
||||
|
||||
In this example *index* handler will always return *500* response. But it is easy
|
||||
In this example *index* handler always returns *500* response. But it is easy
|
||||
to return different responses for different type of errors.
|
||||
|
||||
```rust
|
||||
@ -109,7 +109,7 @@ fn index(req: HttpRequest) -> Result<&'static str, MyError> {
|
||||
## Error helpers
|
||||
|
||||
Actix provides set of error helper types. It is possible to use them to generate
|
||||
specific error responses. We can use helper types for first example with custom error.
|
||||
specific error responses. We can use helper types for the first example with custom error.
|
||||
|
||||
```rust
|
||||
# extern crate actix_web;
|
||||
|
@ -13,6 +13,7 @@ use http2::Error as Http2Error;
|
||||
use http::{header, StatusCode, Error as HttpError};
|
||||
use http::uri::InvalidUri;
|
||||
use http_range::HttpRangeParseError;
|
||||
use serde::de::value::Error as DeError;
|
||||
use serde_json::error::Error as JsonError;
|
||||
pub use url::ParseError as UrlParseError;
|
||||
|
||||
@ -109,6 +110,13 @@ impl ResponseError for JsonError {}
|
||||
/// `InternalServerError` for `UrlParseError`
|
||||
impl ResponseError for UrlParseError {}
|
||||
|
||||
/// Return `BAD_REQUEST` for `de::value::Error`
|
||||
impl ResponseError for DeError {
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
HttpResponse::new(StatusCode::BAD_REQUEST, Body::Empty)
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `InternalServerError` for `HttpError`,
|
||||
/// Response generation can return `HttpError`, so it is internal error
|
||||
impl ResponseError for HttpError {}
|
||||
|
@ -1,11 +1,10 @@
|
||||
use serde_urlencoded;
|
||||
use serde::de::{self, Deserializer, Visitor, Error as DeError};
|
||||
|
||||
use error::{Error, ErrorBadRequest};
|
||||
use httprequest::HttpRequest;
|
||||
|
||||
pub trait HttpRequestExtractor<'de> {
|
||||
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, Error>
|
||||
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, de::value::Error>
|
||||
where T: de::Deserialize<'de>, S: 'static;
|
||||
}
|
||||
|
||||
@ -19,6 +18,7 @@ pub trait HttpRequestExtractor<'de> {
|
||||
/// # extern crate futures;
|
||||
/// #[macro_use] extern crate serde_derive;
|
||||
/// use actix_web::*;
|
||||
/// use actix_web::dev::{Path, HttpRequestExtractor};
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct Info {
|
||||
@ -26,7 +26,7 @@ pub trait HttpRequestExtractor<'de> {
|
||||
/// }
|
||||
///
|
||||
/// fn index(mut req: HttpRequest) -> Result<String> {
|
||||
/// let info: Info = req.extract(Path)?; // <- extract path info using serde
|
||||
/// let info: Info = Path.extract(&req)?; // <- extract path info using serde
|
||||
/// Ok(format!("Welcome {}!", info.username))
|
||||
/// }
|
||||
///
|
||||
@ -40,11 +40,10 @@ pub struct Path;
|
||||
|
||||
impl<'de> HttpRequestExtractor<'de> for Path {
|
||||
#[inline]
|
||||
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, Error>
|
||||
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, de::value::Error>
|
||||
where T: de::Deserialize<'de>, S: 'static,
|
||||
{
|
||||
Ok(de::Deserialize::deserialize(PathExtractor{req: req})
|
||||
.map_err(ErrorBadRequest)?)
|
||||
de::Deserialize::deserialize(PathExtractor{req: req})
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,6 +57,7 @@ impl<'de> HttpRequestExtractor<'de> for Path {
|
||||
/// # extern crate futures;
|
||||
/// #[macro_use] extern crate serde_derive;
|
||||
/// use actix_web::*;
|
||||
/// use actix_web::dev::{Query, HttpRequestExtractor};
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct Info {
|
||||
@ -65,7 +65,7 @@ impl<'de> HttpRequestExtractor<'de> for Path {
|
||||
/// }
|
||||
///
|
||||
/// fn index(mut req: HttpRequest) -> Result<String> {
|
||||
/// let info: Info = req.extract(Query)?; // <- extract query info using serde
|
||||
/// let info: Info = Query.extract(&req)?; // <- extract query info using serde
|
||||
/// Ok(format!("Welcome {}!", info.username))
|
||||
/// }
|
||||
///
|
||||
@ -75,11 +75,10 @@ pub struct Query;
|
||||
|
||||
impl<'de> HttpRequestExtractor<'de> for Query {
|
||||
#[inline]
|
||||
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, Error>
|
||||
fn extract<T, S>(&self, req: &'de HttpRequest<S>) -> Result<T, de::value::Error>
|
||||
where T: de::Deserialize<'de>, S: 'static,
|
||||
{
|
||||
Ok(serde_urlencoded::from_str::<T>(req.query_string())
|
||||
.map_err(ErrorBadRequest)?)
|
||||
serde_urlencoded::from_str::<T>(req.query_string())
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +188,6 @@ impl<'de, S: 'static> Deserializer<'de> for PathExtractor<'de, S>
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use router::{Router, Pattern};
|
||||
use resource::Resource;
|
||||
use test::TestRequest;
|
||||
@ -217,15 +215,15 @@ mod tests {
|
||||
let (router, _) = Router::new("", ServerSettings::default(), routes);
|
||||
assert!(router.recognize(&mut req).is_some());
|
||||
|
||||
let s: MyStruct = req.extract(Path).unwrap();
|
||||
let s: MyStruct = req.extract_path().unwrap();
|
||||
assert_eq!(s.key, "name");
|
||||
assert_eq!(s.value, "user1");
|
||||
|
||||
let s: (String, String) = req.extract(Path).unwrap();
|
||||
let s: (String, String) = req.extract_path().unwrap();
|
||||
assert_eq!(s.0, "name");
|
||||
assert_eq!(s.1, "user1");
|
||||
|
||||
let s: Id = req.extract(Query).unwrap();
|
||||
let s: Id = req.extract_query().unwrap();
|
||||
assert_eq!(s.id, "test");
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ use payload::Payload;
|
||||
use httpmessage::HttpMessage;
|
||||
use httpresponse::{HttpResponse, HttpResponseBuilder};
|
||||
use helpers::SharedHttpInnerMessage;
|
||||
use extractor::HttpRequestExtractor;
|
||||
use extractor::{Path, Query, HttpRequestExtractor};
|
||||
use error::{Error, UrlGenerationError, CookieParseError, PayloadError};
|
||||
|
||||
|
||||
@ -383,6 +383,7 @@ impl<S> HttpRequest<S> {
|
||||
}
|
||||
|
||||
/// Get a reference to the Params object.
|
||||
///
|
||||
/// Params is a container for url parameters.
|
||||
/// Route supports glob patterns: * for a single wildcard segment and :param
|
||||
/// for matching storing that segment of the request url in the Params object.
|
||||
@ -397,14 +398,15 @@ impl<S> HttpRequest<S> {
|
||||
unsafe{ mem::transmute(&mut self.as_mut().params) }
|
||||
}
|
||||
|
||||
/// Extract typed information from path.
|
||||
/// Extract typed information from request's path.
|
||||
///
|
||||
/// By default, in case of error `BAD_REQUEST` response get returned to peer.
|
||||
/// If you need to return different response use `map_err()` method.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate bytes;
|
||||
/// # extern crate actix_web;
|
||||
/// # extern crate futures;
|
||||
/// #[macro_use] extern crate serde_derive;
|
||||
/// use actix_web::*;
|
||||
///
|
||||
@ -414,8 +416,7 @@ impl<S> HttpRequest<S> {
|
||||
/// }
|
||||
///
|
||||
/// fn index(mut req: HttpRequest) -> Result<String> {
|
||||
/// let info: Info = req.extract(Path)?; // <- extract path info using serde
|
||||
/// let info: Info = req.extract(Query)?; // <- extract query info
|
||||
/// let info: Info = req.extract_path()?; // <- extract path info using serde
|
||||
/// Ok(format!("Welcome {}!", info.username))
|
||||
/// }
|
||||
///
|
||||
@ -425,12 +426,60 @@ impl<S> HttpRequest<S> {
|
||||
/// |r| r.method(Method::GET).f(index));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn extract<'a, T, D>(&'a self, ds: D) -> Result<T, Error>
|
||||
pub fn extract_path<'a, T>(&'a self) -> Result<T, Error>
|
||||
where S: 'static,
|
||||
T: de::Deserialize<'a>,
|
||||
D: HttpRequestExtractor<'a>
|
||||
{
|
||||
ds.extract(self)
|
||||
Ok(Path.extract(self)?)
|
||||
}
|
||||
|
||||
/// Extract typed information from request's query string.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_web;
|
||||
/// #[macro_use] extern crate serde_derive;
|
||||
/// use actix_web::{HttpRequest, Result};
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct Info {
|
||||
/// username: String,
|
||||
/// }
|
||||
///
|
||||
/// fn index(mut req: HttpRequest) -> Result<String> {
|
||||
/// let info: Info = req.extract_query()?; // <- extract query info, i.e: /?id=username
|
||||
/// Ok(format!("Welcome {}!", info.username))
|
||||
/// }
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// By default, in case of error, `BAD_REQUEST` response get returned to peer.
|
||||
/// If you need to return different response use `map_err()` method.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate actix_web;
|
||||
/// #[macro_use] extern crate serde_derive;
|
||||
/// use actix_web::{HttpRequest, Result, error};
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct Info {
|
||||
/// username: String,
|
||||
/// }
|
||||
///
|
||||
/// fn index(mut req: HttpRequest) -> Result<String> {
|
||||
/// let info: Info = req.extract_query() // <- extract query information
|
||||
/// .map_err(error::ErrorInternalServerError)?; // <- return 500 in case of error
|
||||
/// Ok(format!("Welcome {}!", info.username))
|
||||
/// }
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
pub fn extract_query<'a, T>(&'a self) -> Result<T, Error>
|
||||
where S: 'static,
|
||||
T: de::Deserialize<'a>,
|
||||
{
|
||||
Ok(Query.extract(self)?)
|
||||
}
|
||||
|
||||
/// Checks if a connection should be kept alive.
|
||||
|
@ -144,7 +144,6 @@ pub use route::Route;
|
||||
pub use resource::Resource;
|
||||
pub use context::HttpContext;
|
||||
pub use server::HttpServer;
|
||||
pub use extractor::{Path, Query};
|
||||
|
||||
// re-exports
|
||||
pub use http::{Method, StatusCode, Version};
|
||||
@ -190,5 +189,5 @@ pub mod dev {
|
||||
pub use param::{FromParam, Params};
|
||||
pub use httpmessage::{UrlEncoded, MessageBody};
|
||||
pub use httpresponse::HttpResponseBuilder;
|
||||
pub use extractor::HttpRequestExtractor;
|
||||
pub use extractor::{Path, Query, HttpRequestExtractor};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user