You can add middleware to **FastAPI** applications.

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**.

## Create a middleware

To create a middleware you use the decorator `@app.middleware("http")` on top of a function.

The middleware function receives:

* The `request`.
* A function `call_next` that will receive the `request` as a parameter.
    * This function will pass the `request` to the corresponding *path operation*.
    * Then it returns the `response` generated by the corresponding *path operation*.
* You can then modify further the `response` before returning it.

```Python hl_lines="9 10 12 15"
{!./src/middleware/tutorial001.py!}
```

!!! tip
    This technique is used in the tutorial about <a href="https://fastapi.tiangolo.com/tutorial/sql-databases/" target="_blank">SQL (Relational) Databases</a>.


!!! tip
    Have in mind that custom proprietary headers can be added <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" target="_blank">using the 'X-' prefix</a>.

    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 <a href="https://fastapi.tiangolo.com/tutorial/cors/" target="_blank">CORS configurations</a>, using the parameter `expose_headers` documented in <a href="https://www.starlette.io/middleware/#corsmiddleware" target="_blank">Starlette's CORS docs</a>.

### Before and after the `response`

You can add code to be run with the `request`,  before any *path operation* receives it. 

And also after the `response` is generated, before returning it.

For example, you could add a custom header `X-Process-Time` containing the time in seconds that it took to process the request and generate a response:

```Python hl_lines="11 13 14"
{!./src/middleware/tutorial001.py!}
```

## Starlette's Middleware

You can also add any other <a href="https://www.starlette.io/middleware/" target="_blank">Starlette Middleware</a>.

These are classes instead of plain functions.

Including:

* `CORSMiddleware` (described in the next section).
* `GZipMiddleware`.
* `SentryMiddleware`.
* ...and others.
