Update Middleware Documentation to use Starlette's way of instantiating middleware
See original GitHub issueFirst Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn’t find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google “How to X in FastAPI” and didn’t find any information.
- I already read and followed all the tutorial in the docs and didn’t find an answer.
- I already checked if it is not related to FastAPI but to Pydantic.
- I already checked if it is not related to FastAPI but to Swagger UI.
- I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- I commit to help with one of those options 👆
Example Code
app.add_middleware(Middleware1)
app.add_middleware(Middleware2)
Description
I noticed that my middleware was running multiple times, and after some extensive Googleing and reading Starlette and FastAPI docs, I came across this issue in the Starlette repo.
The general issue is that when you call add_middleware()
multiple times, it results in re-initializing the middleware each time. While it’s not well documented in Starlette, the authors left a comment in the source code that add_middleware()
is not preferred, and instead should be handled during configuration. Presently, FastAPI makes this possible, because you’re able to do FastAP(middleware=[MyCustomMiddleware])
.
However, in the FastAPI documentation, app.add_middleware()
is what is shown. I think this can cause some issues with middleware usage in FastAPI, and it would help to update the docs and point folks towards the Starlette way of instantiating middleware (i.e. passing a list of middleware to your FastAPI/Starlette instance at initialization).
Operating System
macOS
Operating System Details
No response
FastAPI Version
0.72.0
Python Version
3.9.12
Additional Context
No response
Issue Analytics
- State:
- Created a year ago
- Comments:8 (5 by maintainers)
Sorry, I meant
middleware("http")
was discouraged… I’ve fixed the above. 😅The
app.middleware("http")
decorator is indeed syntax sugar from Starlette (not FastAPI) where the decorated function is treated as thedispatch
method of a newBaseHTTPMiddleware
class. It is also discouraged to use in their source code:See here: https://github.com/encode/starlette/blob/1225ae8404ed0ae0b9170fde1cf824ec3f9c0f2f/starlette/applications.py#L262-L283
Also, @gareth-leake, be aware that there are discussions going on on deprecating BaseHTTPMiddleware. It’s usage is discouraged as well, because it is fundamentally broken. It will not play nicely with contextVars. Recommendation is to rewrite as “pure ASGI” middleware.