-
-
Notifications
You must be signed in to change notification settings - Fork 931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add middleware to Router #1464
Conversation
…/starlette into router-middleware-redux
…/starlette into router-middleware-redux
…/starlette into router-middleware-redux
For what it's worth, I implemented this in Xpresso and it works very nicely. I can also confirm that, aside from breaking the deprecated decorators, moving all middleware to Router and out of App/Starlette would also work in the future, should we choose to take that path (this is what I did in Xpresso). |
@alex-oleshkevich Your opinion is highly appreciated here. :) As we talked on Gitter some time ago, I was pretty skeptical about non-app-level-middlewares at the beginning, but as no one could find a better solution (myself included), I think this is a great addition. I also think this is simpler than #1286 . In any case, I'm going to test this in the following weeks. Everybody, feel free to review this as well. |
Looking forward to seeing this addition! |
I see that in #1286 Tom mentioned the possibility of passing
On this PR, usage is as follows... # apps/admin.py
router = Router(
routes=[
Route(
"/dashboard,
endpoint=...,
)
],
middleware=[Middleware(AdminAuthMiddleware, ...)], # Sub-router-specific middleware
)
# app.py
from .apps import admin
routes = [
Mount(
"/admin",
app=admin.router,
)
]
app = Starlette(
routes=routes,
middleware=..., # App-wide middleware
) But what about It looks like only allowing Instead, with # apps/admin.py
routes = [
Route(
"/dashboard,
endpoint=...,
),
]
# app.py
from .apps import admin
routes = [
Mount(
"/admin",
routes=admin.routes,
middleware=[Middleware(AdminAuthMiddleware, ...)], # Sub-router-specific middleware
)
]
app = Starlette(
routes=routes,
middleware=..., # App-wide middleware
) This style makes the definition of sub-router middleware both closer to where app-level middleware is defined (generally the app This would not only still work with It also seems consistent if we think of Lastly, given all this, and while Tom initially thought "let's also add this to |
So……why not use this code? AdminAuthMiddleware(Mount("/admin", routes=admin.routes), ...) Just a question. I love routing middleware. But I don't think routing middleware is necessary in the |
@abersheeran You might be able to get that to work (does it?), but I suspect there might be issues related to |
I vote for Mount solution. This looks solid and does exactly the same things as Mount already does -> attach another routes/app with extra settings (middleware in our case). |
@florimondmanca You convinced me. ^____^ |
Great points, thank you for bringing it up @florimondmanca I'll cook up an implementation shortly (just rip it out of #1286). |
For those coming here from FastAPI, |
Are there any updates on this? |
@HiperMaximus I think the team has decided to move forward with #1649 instead |
Let's go with #1649. |
Closes #1286
Instead of adding middleware to each
BaseRoute
, we can add it toRouter
.This can then be composed with
Mount
and such to get middleware for a singleBaseRoute
if needed, although this does make adding middleware to a singleBaseRoute
more complicated compared to #1286 since you may have to do a mount -> router -> route just to add middleware. But the most part I think users would be adding middleware to a group of routes not a single route, which works well with having it onRouter
.One nice thing about this is that the behavior of middleware is preserved: you can even modify
scope["path"]
and change the outcome of routing.Another advantage this has over #1286 is that it leaves the door open for us to move middleware from the
Starlette
app toRouter
, so we'd only have middleware in 1 class (I've tested this, it works nicely but requires some braking changes like removingStarlette.build_middleware_stack()
).@alex-oleshkevich what do you think?