A "middleware" is a function that works with every request before it is processed by any specific path operation. And also with every response before returning it.
It takes each request that comes to your application.
It can then do something to that request or run any needed code.
Then it passes the request to be processed by the rest of the application (by some path operation).
It then takes the response generated by the application (by some path operation).
It can do something to that response or run any needed code.
Then it returns the response.
Technical Details
If you have dependencies with yield, the exit code will run after the middleware.
If there were any background tasks (documented later), they will run after all the middleware.
But if you have custom headers that you want a client in a browser to be able to see, you need to add them to your CORS configurations (CORS (Cross-Origin Resource Sharing)) using the parameter expose_headers documented in Starlette's CORS docs.
Technical Details
You could also use from starlette.requests import Request.
FastAPI provides it as a convenience for you, the developer. But it comes directly from Starlette.