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.