pub struct MiddlewareStack { /* private fields */ }Expand description
Ordered collection of middleware with execution logic
The stack executes middleware in two phases:
-
Before dispatch: Middleware execute in registration order
- First error stops the chain
- Session injections accumulate across all middleware
-
After dispatch: Middleware execute in reverse registration order
- Allows proper cleanup/finalization
- Errors replace the result
§Examples
use turul_http_mcp_server::middleware::{MiddlewareStack, McpMiddleware, RequestContext, SessionInjection, MiddlewareError};
use turul_mcp_session_storage::SessionView;
use async_trait::async_trait;
use std::sync::Arc;
struct LoggingMiddleware;
#[async_trait]
impl McpMiddleware for LoggingMiddleware {
async fn before_dispatch(
&self,
ctx: &mut RequestContext<'_>,
_session: Option<&dyn SessionView>,
_injection: &mut SessionInjection,
) -> Result<(), MiddlewareError> {
println!("Request: {}", ctx.method());
Ok(())
}
}
let mut stack = MiddlewareStack::new();
stack.push(Arc::new(LoggingMiddleware));
assert_eq!(stack.len(), 1);Implementations§
Source§impl MiddlewareStack
impl MiddlewareStack
Sourcepub fn push(&mut self, middleware: Arc<dyn McpMiddleware>)
pub fn push(&mut self, middleware: Arc<dyn McpMiddleware>)
Sourcepub async fn execute_before(
&self,
ctx: &mut RequestContext<'_>,
session: Option<&dyn SessionView>,
) -> Result<SessionInjection, MiddlewareError>
pub async fn execute_before( &self, ctx: &mut RequestContext<'_>, session: Option<&dyn SessionView>, ) -> Result<SessionInjection, MiddlewareError>
Execute all middleware before dispatch
§Parameters
ctx: Mutable request contextsession: Optional read-only session viewNoneforinitialize(session doesn’t exist yet)Some(session)for all other methods
§Returns
Ok(SessionInjection): All middleware succeeded, contains accumulated injectionsErr(MiddlewareError): First middleware that failed
§Execution
- Execute each middleware in registration order
- Accumulate session injections from all middleware
- Stop on first error
Sourcepub async fn execute_after(
&self,
ctx: &RequestContext<'_>,
result: &mut DispatcherResult,
) -> Result<(), MiddlewareError>
pub async fn execute_after( &self, ctx: &RequestContext<'_>, result: &mut DispatcherResult, ) -> Result<(), MiddlewareError>
Execute all middleware after dispatch
§Parameters
ctx: Read-only request contextresult: Mutable dispatcher result
§Returns
Ok(()): All middleware succeededErr(MiddlewareError): First middleware that failed
§Execution
- Execute each middleware in reverse registration order
- Stop on first error
- Allow middleware to modify result
Trait Implementations§
Source§impl Clone for MiddlewareStack
impl Clone for MiddlewareStack
Source§fn clone(&self) -> MiddlewareStack
fn clone(&self) -> MiddlewareStack
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Default for MiddlewareStack
impl Default for MiddlewareStack
Source§fn default() -> MiddlewareStack
fn default() -> MiddlewareStack
Returns the “default value” for a type. Read more
Auto Trait Implementations§
impl Freeze for MiddlewareStack
impl !RefUnwindSafe for MiddlewareStack
impl Send for MiddlewareStack
impl Sync for MiddlewareStack
impl Unpin for MiddlewareStack
impl !UnwindSafe for MiddlewareStack
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more