Middleware
Middleware hooks all requests/responses and their derivatives of dyer, including Task
, Affix
, Request
, Response
, error
and entiry
. it's flexible, low-level, scale to modify the data flow of dyer.
Inspection of Middleware
before we dive deeper into what middleware is, let take a look at some simplified code of Middleware
#![allow(unused)] fn main() { pub struct MiddleWare<'md, E> { handle_affix: Option<&'md dyn for<'a> Fn(&'a mut Vec<Affix>, &'a mut App<E>)>, handle_task: Option<&'md dyn for<'a> Fn(&'a mut Vec<Task>, &'a mut App<E>)>, handle_req: Option<&'md dyn for<'a> Fn(&'a mut Vec<Request>, &'a mut App<E>)>, handle_res: Option<&'md dyn for<'a> Fn(&'a mut Vec<Response>, &'a mut App<E>)>, handle_entity: Option<&'md dyn for<'a> Fn(&'a mut Vec<E>, &'a mut App<E>)>, handle_yerr: Option< &'md dyn for<'a> Fn( &'a mut Vec<Result<Response, MetaResponse>>, &'a mut App<E>, )>, handle_err: Option< &'md dyn for<'a> Fn( &'a mut Vec<Result<Response, MetaResponse>>, &'a mut App<E>, )>, // some other fields ... } }
As shown above, it accepts some nullable async function as handlers for requests, response and its derivatives. let's log out errors:
#![allow(unused)] fn main() { pub async fn log_err(errs: &mut Vec<Result<Response, MetaResponse>, _: &mut App<E>> { for r in errs.iter() { match r { Ok(data) => { println!("failed request to {}", data.metas.info.uri); }, Err(e) => { println!("failed request to {}", e.info.uri); } } } } // set up `handle_err` let middleware = MiddleWare::builder().err_mut(&log_err).build("marker".into()); }
that middleware will log out uri of failed response.