Signals `http.middleware.before` and `http.middleware.after` are dispatched for _every_ middleware
See original GitHub issueFor a single request, the signals http.middleware.before
and http.middleware.after
are dispatched for every middle on the app.
Example app:
from sanic import Sanic
from sanic.response import html
app = Sanic(__name__)
@app.middleware("request")
def my_middleware1(request):
print("Middleware 1 ran", flush=True)
@app.middleware("request")
def my_middleware2(request):
print("Middleware 2 ran", flush=True)
@app.signal("http.middleware.before", condition={"attach_to": "request"})
def handle_mw_before(request, response=None):
print("Before middleware", flush=True)
@app.signal("http.middleware.after", condition={"attach_to": "request"})
def handle_mw_after(request, response):
print("After middleware", flush=True)
@app.get("/")
def index(request):
return html("<p>hello world</p>")
if __name__ == "__main__":
app.run(debug=True, auto_reload=False, access_log=False)
Output:
[2022-01-04 13:57:50 +1000] [47672] [INFO] Starting worker [47672]
[2022-01-04 13:57:54 +1000] [47672] [DEBUG] Dispatching signal: http.middleware.before
Before middleware
Middleware 1 ran
[2022-01-04 13:57:54 +1000] [47672] [DEBUG] Dispatching signal: http.middleware.after
After middleware
[2022-01-04 13:57:54 +1000] [47672] [DEBUG] Dispatching signal: http.middleware.before
Before middleware #<--- Run again
Middleware 2 ran
[2022-01-04 13:57:54 +1000] [47672] [DEBUG] Dispatching signal: http.middleware.after
After middleware #<--- Run again
Applicable section of code: https://github.com/sanic-org/sanic/blob/a7bc8b56bab01e066357e6dcc67c0dc9df864298/sanic/app.py#L1346-L1372
It appears this is done intentionally. I don’t know what the usefulness of running a handler for every middleware is, except for perhaps debug tracing or handler logger.
Maybe it makes sense to create two new signals like http.middleware.before_all
and http.middleware.after_all
, in a place like this:
await self.dispatch(
"http.middleware.before_all",
inline=True,
context={
"request": request,
"response": None,
},
condition={"attach_to": "request"},
)
response = None
if applicable_middleware and not request.request_middleware_started:
request.request_middleware_started = True
for middleware in applicable_middleware:
await self.dispatch(
"http.middleware.before",
inline=True,
context={
"request": request,
"response": None,
},
condition={"attach_to": "request"},
)
response = middleware(request)
if isawaitable(response):
response = await response
await self.dispatch(
"http.middleware.after",
inline=True,
context={
"request": request,
"response": None,
},
condition={"attach_to": "request"},
)
if response:
break
await self.dispatch(
"http.middleware.after_all",
inline=True,
context={
"request": request,
"response": response,
},
condition={"attach_to": "request"},
)
return response
Issue Analytics
- State:
- Created 2 years ago
- Comments:9 (7 by maintainers)
Top Results From Across the Web
What is the difference between signal and middleware in ...
Middleware is a framework of hooks into Django's request/response processing. It's a light, low-level “plugin” system for globally altering ...
Read more >Making and Using HTTP Middleware
Making and using middleware in Go is fundamentally simple. We want to: ... I'll explain how. ... In this code we put our...
Read more >Middlewares - Watermill
SignalsHandler ) // Router level middleware are executed for every message sent to the router router.AddMiddleware( // CorrelationID will copy the ...
Read more >Using Next.js' middleware and Edge Functions
js, use middleware to intercept an HTTP request and process it before it reaches the route handler. So, in this post, we'll learn...
Read more >Signals
You can attach them just like any other signal to an application or blueprint instance. ... http.middleware.before, request, response ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
We should probably also include a lifecycle diagram in the docs with the flow of handlers, middleware, and signals.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If this is incorrect, please respond with an update. Thank you for your contributions.