Middleware Registry Reference
Framework M web requests pass through a priority-ordered ASGI middleware stack. The MiddlewareRegistry is the central discovery and ordering mechanism for that stack.
Overview
MiddlewareRegistryis a singleton registry.- Middlewares declare a
priorityclass attribute. Lower values run first (outer layer). - Built-in middlewares are registered programmatically in
create_app(). - Additional middlewares are auto-discovered from the
framework_m.middlewareentry point group. - Deployments can override per-middleware settings via
framework_config.tomlunder[web.middleware].
Priority Bands
| Range | Purpose | Examples |
|---|---|---|
| 0–50 | Security / early processing | rate limiting, CSRF |
| 50–100 | Authentication / identity | auth middleware |
| 100–150 | General purpose | recent document tracking |
| 150–200 | Compression / transformation | response transforms |
| 200+ | Observability / tracing | metrics |
Built-in Middlewares
| Name | Class | Priority | Purpose |
|---|---|---|---|
rate_limit | Litestar RateLimitConfig.middleware | 10 | Request throttling |
csrf | CSRFMiddlewareFactory result | 20 | Origin/Referer validation |
idempotency | IdempotencyMiddleware | 30 | Idempotent request deduplication |
auth | AuthMiddleware | 50 | Authentication resolution |
federated_redirect | FederatedRedirectMiddleware | 55 | OIDC redirect in federated mode |
locale | LocaleResolutionMiddleware | 60 | Locale resolution |
recent_document | RecentDocumentMiddleware | 120 | Recently viewed document tracking |
metrics | MetricsMiddleware | 200 | Prometheus metrics |
Entry Point Registration
Any installed package can contribute middleware by declaring it under framework_m.middleware:
[project.entry-points."framework_m.middleware"]
my_audit = "my_app.middleware:MyAuditMiddleware"
The entry point name is the middleware identifier. Multiple packages registering the same name follow last-wins semantics, matching the bootstrap override pattern.
# my_app/middleware.py
from litestar.types import ASGIApp, Receive, Scope, Send
class MyAuditMiddleware:
priority = 130
def __init__(self, app: ASGIApp) -> None:
self.app = app
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
await self.app(scope, receive, send)
Configuration Overrides
Per-middleware settings live under [web.middleware.<name>] in framework_config.toml:
[web.middleware.recent_document]
enabled = false
[web.middleware.my_audit]
priority = 25
kwargs = { header_name = "X-Audit-Log" }
| Key | Type | Description |
|---|---|---|
enabled | boolean | Enable or disable the middleware. |
priority | integer | Override execution order. |
kwargs | dict | Merge additional constructor keyword arguments. |
API
MiddlewareRegistry
Singleton registry for ASGI middleware.
from framework_m_standard.adapters.web.middleware_registry import MiddlewareRegistry
registry = MiddlewareRegistry.get_instance()
registry.register(
MyMiddleware,
name="my_middleware",
priority=120,
kwargs={"foo": "bar"},
)
create_middleware_stack
Builds the final Litestar middleware list.
from framework_m_standard.adapters.web.middleware_registry import (
create_middleware_stack,
)
stack = create_middleware_stack()
The function:
- Scans
framework_m.middlewareentry points. - Applies
[web.middleware]config overrides. - Sorts by priority.
- Returns
list[DefineMiddleware].
RecentDocumentMiddleware
Tracks recently viewed documents for Desk UI users.
- Intercepts successful
GETrequests to registered DocType resource endpoints. - Reads the authenticated user from
scope["state"]["user"]. - Upserts a
RecentDocumentrow per user + doctype + document. - Resolves the document display name by re-reading the target document.
Enable or configure it via framework_config.toml:
[web.middleware.recent_document]
enabled = true
priority = 120