MiddlewareStack — Aquilia Documentation
Comprehensive guide and documentation for MiddlewareStack in the Aquilia framework. View API reference, examples, and implementation patterns.
MIDDLEWARE / STACK & COMPOSITION Middleware Stack The MiddlewareStack manages middleware registration, verifies structural contracts at startup, and compiles the execution pipelines. Startup Contract Validation When you register middleware using .middleware() or direct stack.add(), Aquilia performs four rigorous inspection checks using Python's reflection APIs before running the server: 1. Inheritance Check Class instances must inherit from the Middleware base class. Raw functions bypass this check if they are directly callable. 2. Callability Check The registered object must be callable (i.e. possess an active __call__ method or be a routine). 3. Parameter Count Check Signature inspection (via inspect.signature) enforces exactly three parameters: (request, ctx, next_handler). Binds are verified at registration. 4. Async Coroutine Check The entrypoint MUST be a coroutine function (async def). Sync callables trigger a runtime TypeError at boot. Performance Optimizations: Fast Path For latency-critical routes, building the full middleware chain adds microsecond overhead. Aquilia resolves this via two methods: build_handler(final_handler) Compiles the complete chain. Outermost middleware runs first, tracing frames if enabled. build_fast_handler(final_handler) Compiles a minimal chain. Dynamically strips non-essential, purely informational middlewares (specifically LoggingMiddleware and TimeoutMiddleware) while preserving security boundaries like CORSMiddleware and ExceptionMiddleware . Manipulating the Stack from aquilia.middleware import MiddlewareStack from my_middlewares import SecurityMiddleware, LoggingMiddleware, Handler stack = MiddlewareStack() # 1. Register with scopes and priority stack.add(SecurityMiddleware(), scope="global", priority=10, name="security") stack.add(LoggingMiddleware(), scope="global", priority=90, name="logging") # 2. Build normal handler (executes: Security -> Logging -> Handler) handler = stack.build_handler(final_handler=Handler) # 3. Build fast handler (executes: Security -> Handler; skips Logging) fast_handler = stack.build_fast_handler(final_handler=Handler) Priority Reference (from AquiliaServer._setup_middleware) These are the exact priority numbers AquiliaServer assigns when it wires each built-in middleware — not the fictional numbers you'll find in older docs. Lower number = wraps closer to the outside = runs first on the way in. Class Priority Always On? Fast-Path Skippable ))} ExceptionMiddleware 1 (hardcoded fallback, or your own chain) only if no .middleware() chain configured NO RequestIdMiddleware 10 (hardcoded fallback, or your own chain) only if no .middleware() chain configured NO TimeoutMiddleware 18 (MiddlewareChain.production() preset) only if in your chain YES CompressionMiddleware 15 (MiddlewareChain.production() preset) only if in your chain NO LoggingMiddleware your choice — not auto-registered no — must add explicitly YES Source: aquilia/server.py AquiliaServer._setup_middleware(), plus the individual self.middleware_stack.add(...) calls scattered through session/auth, templates, i18n, cache, and versioning setup. Only build_fast_handler()'s _FAST_SKIP_NAMES frozenset ( "LoggingMiddleware", "TimeoutMiddleware" '}) is skippable on the fast path — every other middleware always runs, whether the request needs it or not. Overview Built-in Middleware )
Go to Homepage