mirror of
https://github.com/actix/actix-web.git
synced 2024-11-26 03:21:08 +00:00
add appl builder async method; add async handler section
This commit is contained in:
parent
e6feec62a8
commit
c3a0a4457a
4 changed files with 56 additions and 9 deletions
|
@ -56,7 +56,7 @@ fn index(req: HttpRequest<AppState>) -> String {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
Application::build("/", AppState{counter: Cell::new(0)})
|
Application::build("/", AppState{counter: Cell::new(0)})
|
||||||
.resource("/", |r| r.handler(Method::GET, index)))
|
.resource("/", |r| r.handler(Method::GET, index))
|
||||||
.finish();
|
.finish();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -143,7 +143,7 @@ fn main() {
|
||||||
HttpServer::new(
|
HttpServer::new(
|
||||||
Application::default("/")
|
Application::default("/")
|
||||||
.resource("/", |r| r.handler(
|
.resource("/", |r| r.handler(
|
||||||
Method::GET, |req| {Ok(MyObj{name: "user".to_owned()})})))
|
Method::GET, |req| {MyObj{name: "user".to_owned()}})))
|
||||||
.serve::<_, ()>("127.0.0.1:8088").unwrap();
|
.serve::<_, ()>("127.0.0.1:8088").unwrap();
|
||||||
|
|
||||||
println!("Started http server: 127.0.0.1:8088");
|
println!("Started http server: 127.0.0.1:8088");
|
||||||
|
@ -166,3 +166,35 @@ impl Into<Result<HttpResponse>> for MyObj {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Async handlers
|
||||||
|
|
||||||
|
There are two different types of async handlers.
|
||||||
|
|
||||||
|
Response object could be generated asynchronously. In this case handle must
|
||||||
|
return `Future` object that resolves to `HttpResponse`, i.e:
|
||||||
|
|
||||||
|
```rust,ignore
|
||||||
|
fn index(req: HttpRequest) -> Box<Future<HttpResponse, Error>> {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This handler can be registered with `ApplicationBuilder::async()` and
|
||||||
|
`Resource::async()` methods.
|
||||||
|
|
||||||
|
Or response body can be generated asynchronously. In this case body
|
||||||
|
must implement stream trait `Stream<Item=Bytes, Error=Error>`, i.e:
|
||||||
|
|
||||||
|
|
||||||
|
```rust,ignore
|
||||||
|
fn index(req: HttpRequest) -> HttpResponse {
|
||||||
|
let body: Box<Stream<Item=Bytes, Error=Error>> = Box::new(SomeStream::new());
|
||||||
|
|
||||||
|
HttpResponse::Ok().
|
||||||
|
.content_type("application/json")
|
||||||
|
.body(Body::Streaming(body)).unwrap()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Both methods could be combined. (i.e Async response with streaming body)
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use futures::Future;
|
||||||
|
|
||||||
use route::{RouteHandler, WrapHandler, Reply, Handler};
|
use error::Error;
|
||||||
|
use route::{RouteHandler, Reply, Handler, WrapHandler, AsyncHandler};
|
||||||
use resource::Resource;
|
use resource::Resource;
|
||||||
use recognizer::{RouteRecognizer, check_pattern};
|
use recognizer::{RouteRecognizer, check_pattern};
|
||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
|
use httpresponse::HttpResponse;
|
||||||
use channel::HttpHandler;
|
use channel::HttpHandler;
|
||||||
use pipeline::Pipeline;
|
use pipeline::Pipeline;
|
||||||
use middlewares::Middleware;
|
use middlewares::Middleware;
|
||||||
|
@ -204,6 +207,18 @@ impl<S> ApplicationBuilder<S> where S: 'static {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This method register async handler for specified path prefix.
|
||||||
|
/// Any path that starts with this prefix matches handler.
|
||||||
|
pub fn async<P, F, R>(&mut self, path: P, handler: F) -> &mut Self
|
||||||
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
|
R: Future<Item=HttpResponse, Error=Error> + 'static,
|
||||||
|
P: Into<String>,
|
||||||
|
{
|
||||||
|
self.parts.as_mut().expect("Use after finish")
|
||||||
|
.handlers.insert(path.into(), Box::new(AsyncHandler::new(handler)));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Construct application
|
/// Construct application
|
||||||
pub fn middleware<T>(&mut self, mw: T) -> &mut Self
|
pub fn middleware<T>(&mut self, mw: T) -> &mut Self
|
||||||
where T: Middleware + 'static
|
where T: Middleware + 'static
|
||||||
|
|
|
@ -5,7 +5,7 @@ use http::Method;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use route::{Reply, RouteHandler, WrapHandler, Handler, StreamHandler};
|
use route::{Reply, Handler, RouteHandler, AsyncHandler, WrapHandler};
|
||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
use httpresponse::HttpResponse;
|
use httpresponse::HttpResponse;
|
||||||
use httpcodes::{HTTPNotFound, HTTPMethodNotAllowed};
|
use httpcodes::{HTTPNotFound, HTTPMethodNotAllowed};
|
||||||
|
@ -70,7 +70,7 @@ impl<S> Resource<S> where S: 'static {
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Future<Item=HttpResponse, Error=Error> + 'static,
|
R: Future<Item=HttpResponse, Error=Error> + 'static,
|
||||||
{
|
{
|
||||||
self.routes.insert(method, Box::new(StreamHandler::new(handler)));
|
self.routes.insert(method, Box::new(AsyncHandler::new(handler)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default handler is used if no matched route found.
|
/// Default handler is used if no matched route found.
|
||||||
|
|
|
@ -154,7 +154,7 @@ impl<S, H, R> RouteHandler<S> for WrapHandler<S, H, R>
|
||||||
|
|
||||||
/// Async route handler
|
/// Async route handler
|
||||||
pub(crate)
|
pub(crate)
|
||||||
struct StreamHandler<S, R, F>
|
struct AsyncHandler<S, R, F>
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Future<Item=HttpResponse, Error=Error> + 'static,
|
R: Future<Item=HttpResponse, Error=Error> + 'static,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
|
@ -163,17 +163,17 @@ struct StreamHandler<S, R, F>
|
||||||
s: PhantomData<S>,
|
s: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, R, F> StreamHandler<S, R, F>
|
impl<S, R, F> AsyncHandler<S, R, F>
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Future<Item=HttpResponse, Error=Error> + 'static,
|
R: Future<Item=HttpResponse, Error=Error> + 'static,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
{
|
{
|
||||||
pub fn new(f: F) -> Self {
|
pub fn new(f: F) -> Self {
|
||||||
StreamHandler{f: Box::new(f), s: PhantomData}
|
AsyncHandler{f: Box::new(f), s: PhantomData}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, R, F> RouteHandler<S> for StreamHandler<S, R, F>
|
impl<S, R, F> RouteHandler<S> for AsyncHandler<S, R, F>
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Future<Item=HttpResponse, Error=Error> + 'static,
|
R: Future<Item=HttpResponse, Error=Error> + 'static,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
|
|
Loading…
Reference in a new issue