Complete Guide to FastAPI Middleware
📂 Stage: Stage 2 - Advanced Black Technology (Core) 🔗 Related chapters: FastAPI异步编程深度解析 · FastAPIexception-handling
Table of contents
1. Basic introduction to middleware
What is middleware?
You can think of middleware as an "onion skin" wrapped around the entire FastAPI application. Each request must pass through this skin before reaching the actual routing handler; and when the handler generates a response, the response passes through these skins again in reverse order before being returned to the client.
From a technical point of view, middleware is a hook function that is executed between the request and the response. It can:
- Do some preprocessing (such as identity verification, logging) before the request reaches the route
- Secondary processing of the response after the route generates it (e.g. compression, adding security headers)
In this way, all routes automatically gain these capabilities, and you no longer have to write the same logic repeatedly in each interface.
Position in request life cycle
The figure below shows the execution sequence of three different middlewares (logging, CORS, GZip) in the request/response pipeline. Requests are passed from top to bottom, and responses are returned from bottom to top.
Middleware vs Dependency Injection
FastAPI provides two ways to implement "cross-cutting concerns": Middleware and Dependency Injection. Many novices will wonder: they can both perform additional logic in requests. What is the difference?
Simply put:
- Middleware acts on all requests and is suitable for global, common processing unrelated to business (such as logging, compression, security headers).
- Dependency Injection is bound to specific routes on demand, which is suitable for operations closely related to routing parameters or business logic (such as permission verification, database sessions).
The specific comparison is as follows:
Core Advantages
- Global Unification: Avoid writing the same logic repeatedly in each route and reduce code redundancy.
- Separation of concerns: Decouple logs, security, etc. from the business to make the code clearer.
- Flexible reuse: The same middleware can be applied to multiple projects, or even packaged into independent modules.
- Performance friendly: FastAPI’s middleware naturally supports asynchronous
async/await, will not block the event loop.
2. Basics of middleware development
FastAPI (the underlying layer is based on Starlette) provides two ways of writing middleware, which are suitable for scenarios of different complexity.
Method 1: Decorator middleware (lightweight and fast)
If you only need to implement a very simple function, such as counting the time consumption of each interface, and do not need to initialize the configuration or internal state, then directly use@app.middleware("http")Decorators are the fastest way.
💡 Tips:
call_nextResponsible for calling the next processing link, which will eventually execute the routing function. You can insert logic before and after it. This is the core pattern of middleware.
Method 2: InheritanceBaseHTTPMiddleware(suitable for complex functions)
When your middleware needs to receive initialization parameters (such as specifying which paths to skip) or maintain internal state (such as counting some indicators), it should inherit Starlette'sBaseHTTPMiddlewarekind.
📌 Note:
dispatchThe function of the method is exactly the same as the decorator version, but the writing method is different. you candispatchAccess securely withinselfto read the initialization configuration.
Three. Commonly used official/built-in middleware
The FastAPI/Starlette ecosystem has built-in some very practical middleware. Please give priority to using them when developing to avoid reinventing the wheel.
1. CORS cross-domain middleware
CORSMiddlewareIt is a middleware officially maintained by FastAPI and specifically solves the cross-domain restrictions of browsers. Proper configuration can avoid a series of strange front-end and back-end joint debugging problems.
Recommended configuration for production environment
⚠️ Safety reminder: Do not use in production environment
allow_origins=["*"], especially if you also setallow_credentials=True- This will cause the browser to reject the cross-origin request outright.
2. GZip response compression middleware
GZipMiddlewareFrom Starlette, it can automatically compress text-based responses such as JSON, HTML, JS, etc., significantly reducing network transmission volume. Compression ratios can often reach over 70%.
Configuration is extremely simple, typically requiring just one line of code to enable global compression.
IV. Advanced Custom Middleware Implementation
After mastering the basic usage, let's look at some custom middleware that are very practical in real business.
1. Security header middleware
Security organizations such as OWASP recommend adding a series of security headers to responses to protect against common web attacks. We can add these headers uniformly through a middleware.
In this way, no matter which interface returns the response, these protection headers will automatically be included.
2. Unified error handling middleware
In large projects, we usually catch all exceptions that are not handled by the routing layer and convert them into structured JSON error objects to avoid exposing internal stack details to the client.
🔒 Recommendations for production environment:
DEBUGThe mode is controlled by environment variables. The online environment must hide detailed error stacks to prevent leakage of sensitive code information.
5. Best Practices in Production Environment
Although middleware is good, it can cause trouble if used incorrectly. A few core principles of practice are summarized below.
1. Control the registration sequence of middleware
Requests will be made as perapp.add_middleware()The calling sequence passes through each middleware in turn; the response passes in the reverse direction. So the order is crucial:
- CORS middleware is usually placed in the front position in order to intercept and process the browser's preflight request as early as possible (
OPTIONS)。 - Error handling middleware must be placed at the end so that exceptions thrown by all middleware before it and inside the route can be caught.
2. Avoid performance pitfalls in middleware
- Do not perform time-consuming operations: such as checking the database in middleware and calling external APIs, unless this is a necessary global security check. If you must do it, make sure it is done asynchronously.
- Quickly skip irrelevant paths: Yes
/docs、/healthWait for the route to return as soon as possiblecall_next, to avoid wasting computing resources. - KEEP ASync: All IO operations should use
async/await, otherwise it will block the entire event loop and bring down the entire application.
6. Summary
FastAPI middleware is a powerful tool for realizing global cross-cutting concerns. Proper use of it can greatly improve application security, performance and code maintainability. Finally, let’s review the key points:
- Prefer official/built-in middleware (CORS, GZip), they are proven and ready to use out of the box.
- Lightweight function recommended
@app.middleware("http")Decorator, complex function is inheritedBaseHTTPMiddleware。 - Strictly control the registration sequence and use
skip_pathsetc. to filter paths that do not need to be processed. - Fully test the production environment and be careful to avoid synchronization blocking and hiding internal error details.
After mastering these skills, you can build a robust and efficient FastAPI application by combining different middleware like building blocks.
🔗 Extended reading

