Trait arc_reactor::proto::MiddleWare [−][src]
pub trait MiddleWare<T: Sized>: MiddleWareClone<T> + Sync + Send { fn call(&self, param: T) -> MiddleWareFuture<T>; }
The middleware Trait. In arc-reactor the middleware system is designed to be as intuitive and as simple as possible.
How it works.
Think of a MiddleWare<T>
as a function that returns Result<T, Response>
E.g A middleware is given a Request
to do some processing, if that
MiddleWare, returns Ok(request). Then the returned request is passed to the
next middleware or route handler.
use arc_reactor::prelude::*; //#### #[middleware(Request)] fn hasAccessToken(req: Request) { let token = req.query::<AccessToken>(); if let Some(user) = await!(db::fetchUserFromToken(token)).ok() { req.set::<User>(user); return Ok(req); } let res = Response::new().with_status(401); return Err(res) } //#### #[service] fn UserService(req: Request, res: Response) { let user = req.get::<User>().unwrap(); // It's safe to unwrap here, because the service is only called when `hasAccessToken` returns Ok(request). .... } fn main() { let router = Router::new() .get2("/user", mw![hasAccessToken], UserService); ..... // start the server mount the routes. }
Working With a Vec<MiddleWare<T>>
The same rules as above applies, each middleware pass the request among
themselves to do processing. If any of them returns Err(Response)
, the
rest of the middlewares are skipped as well as the route handler.
use arc_reactor::prelude::*; //#### #[middleware(Request)] fn middleware1(req: Request) { println!("will be executed"); return Ok(req) } //#### #[middleware(Request)] fn middleware2(req: Request) { println!("will always be called, because middleware1 always returns Ok(request)"); return Err(Response::new().with_status(401)) } //#### #[middleware(Request)] fn middleware3(req: Request) { println!("will never be called"); return Ok(req) } //#### #[service] fn TestService(req: Request, res: Response) { println!("Will never be called, because middleware 2 returns an Err(response)") ...... } fn main() { let router = Router::new() .get2("/user", mw![middleware1, middleware2, middleware3], TestService); // note that the order of middlewares matter! ..... // start the server mount the routes. }
Note
Please note that you would probably never have a reason to implement this trait on your type directly.
Instead you'll use the middleware proc_macro
#[middleware]
to decorate your
functions. The proc_macro makes MiddleWare
's aasynchronous by default. so
you can await!()
on futures.
Required Methods
fn call(&self, param: T) -> MiddleWareFuture<T>
Implementations on Foreign Types
impl MiddleWare<Request> for Vec<Box<MiddleWare<Request>>>
[src]
impl MiddleWare<Request> for Vec<Box<MiddleWare<Request>>>
This enables a vector of MiddleWare<Request>
to behave like a single
MiddleWare<Request>
returning Err(Response)
in any of the
MiddleWare<Request>
will cause the rest of the middlewares to be skipped.
Note that there's a conveinience macro mw
that allows you not write boxes
everywhere.
fn call(&self, request: Request) -> MiddleWareFuture<Request>
[src]
fn call(&self, request: Request) -> MiddleWareFuture<Request>
impl MiddleWare<Response> for Vec<Box<MiddleWare<Response>>>
[src]
impl MiddleWare<Response> for Vec<Box<MiddleWare<Response>>>
This enables a vector of MiddleWare<Request>
to behave like a single
MiddleWare<Request>
returning Err(Response)
in any of the
MiddleWare<Request>
will cause the rest of the middlewares to be skipped.
Note that there's a conveinient macro mw
that allows you not write
boxes everywhere.
fn call(&self, response: Response) -> MiddleWareFuture<Response>
[src]
fn call(&self, response: Response) -> MiddleWareFuture<Response>
impl MiddleWare<Request> for Box<MiddleWare<Request>>
[src]
impl MiddleWare<Request> for Box<MiddleWare<Request>>
fn call(&self, item: Request) -> MiddleWareFuture<Request>
[src]
fn call(&self, item: Request) -> MiddleWareFuture<Request>
impl MiddleWare<Response> for Box<MiddleWare<Response>>
[src]
impl MiddleWare<Response> for Box<MiddleWare<Response>>
fn call(&self, item: Response) -> MiddleWareFuture<Response>
[src]
fn call(&self, item: Response) -> MiddleWareFuture<Response>
Implementors
impl<T> MiddleWare<Request> for T where
T: Fn(Request) -> MiddleWareFuture<Request> + Send + Sync + Clone + 'static,impl<T> MiddleWare<Response> for T where
T: Fn(Response) -> MiddleWareFuture<Response> + Send + Sync + Clone + 'static,impl MiddleWare<Request> for BodyParser
impl MiddleWare<Request> for StaticFileServer