Starlette - Multiple middleware orders #2278
-
Hi, I'm wondering why the function Let's be more specific. I use starlette session middleware ( So when I declare my middlewares, logically I'm doing this based on the dependancies: from starlette.middleware.sessions import SessionMiddleware
from my.app.middleware import MyCustomMiddlewareThatUsedSessionInside
app.add_middleware(SessionMiddleware, secret_key="xxx", max_age=None)
app.add_middleware(MyCustomMiddlewareThatUsedSessionInside) But, I have this error:
Now, if I change the order of middlewares, that works: app.add_middleware(MyCustomMiddlewareThatUsedSessionInside) # Need to be before SessionMiddleware
app.add_middleware(SessionMiddleware, secret_key="xxx", max_age=None) I don't know if there's a reason for that, or if it's just a misunderstanding on my side. But at first glance I find it rather illogical. Thanks. Actual def add_middleware(self, middleware_class: type, **options: typing.Any) -> None:
if self.middleware_stack is not None: # pragma: no cover
raise RuntimeError("Cannot add middleware after an application has started")
self.user_middleware.insert(0, Middleware(middleware_class, **options)) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Yes. The idea is that each middleware you add wraps the current application. So... If you have an app A, and you add the middleware B, you now have B(A), which is now another application. When you add a middleware C, conceptually you should think that you have the B(A) application, and not only A. Meaning that you'll have the C(B(A)) application from now on. |
Beta Was this translation helpful? Give feedback.
-
@Kludex Your description makes it so clear, I feel like it should be added to the middleware docs. |
Beta Was this translation helpful? Give feedback.
Yes.
The idea is that each middleware you add wraps the current application. So... If you have an app A, and you add the middleware B, you now have B(A), which is now another application. When you add a middleware C, conceptually you should think that you have the B(A) application, and not only A. Meaning that you'll have the C(B(A)) application from now on.