-
-
Notifications
You must be signed in to change notification settings - Fork 314
Description
I need to apply both an authentication handler (via auth_required=True) and a custom pre-processing middleware (via @before_request) to the same route (e.g., /index). For example:
Authentication: Validate permissions through the BasicAuthHandler.
Custom Filter: Execute non-auth tasks like request logging or input sanitization.
But when combined, they cause a route conflict. How can I achieve this in Robyn?
Code Attempt
@app.get("/index", auth_required=True)
async def index(request):
return "Index Page"
@app.before_request("/index")
async def custom_filter(request: Request):
print("Checking request headers...")
return request
Error Observed:
thread '<unnamed>' panicked at src\server.rs:389:14:
called `Result::unwrap()` on an `Err` value: insertion failed due to conflict with previously registered route: /index
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Questions:
Design Philosophy: Does Robyn intentionally limit one middleware per route, or is this a configuration issue?
If applicable, could features like middleware priority ordering or route-scoped middleware grouping be added? Example:
# Hypothetical API
@app.get("/secure")
@app.middleware(
AuthMiddleware(),
CustomFilterMiddleware(),
order=["auth", "filter"]
)
async def secure_route(request):
return "Secure Data"
and...
I noticed the following code in the implementation:
def add_auth_middleware(self, endpoint: str):
"""
This method adds an authentication middleware to the specified endpoint.
"""
injected_dependencies: dict = {}
def decorator(handler):
@wraps(handler)
def inner_handler(request: Request, *args):
if not self.authentication_handler:
raise AuthenticationNotConfiguredError()
identity = self.authentication_handler.authenticate(request)
if identity is None:
return self.authentication_handler.unauthorized_response
request.identity = identity
return request
self.add_route(
MiddlewareType.BEFORE_REQUEST,
endpoint,
inner_handler,
injected_dependencies,
)
return inner_handler
return decorator
This implies that the authentication handler is inherently registered as a MiddlewareType.BEFORE_REQUEST middleware. Therefore, when combining auth_required=True with custom @app.before_request on the same route, we're essentially creating two BEFORE_REQUEST middlewares for the same endpoint, leading to conflicts.
To verify this hypothesis, I tried registering multiple @before_request handlers on the same endpoint:
@app.before_request("/index")
async def hello_before_request(request: Request):
print("before_request1111111111111...")
print("Custom filtering processing, unrelated to permissions....")
return request
@app.before_request("/index")
async def hello_before_request2(request: Request):
print("before_request2222222222222...")
print("Multiple filtering processes...")
return request
This indeed triggered the same error:
called `Result::unwrap()` on an `Err` value:
insertion failed due to conflict with previously registered route: /index
This confirms that Robyn's current architecture doesn't allow multiple BEFORE_REQUEST middlewares on the same route, whether they're authentication handlers or custom middlewares??
How should I handle it...