FastAPI Training: Middleware Explained
Key Concepts
Middleware in FastAPI is a powerful tool that allows you to process requests and responses globally across your application. It enables you to add functionality such as logging, authentication, and request/response modification. Here are the key concepts:
- Middleware Function: A function that processes each request and response.
- Request and Response Processing: Middleware can intercept and modify requests before they reach the route handlers and responses before they are sent back to the client.
- Order of Execution: Middleware functions are executed in the order they are added to the application.
Middleware Function
A middleware function in FastAPI is defined using the app.middleware("http")
decorator. This function takes two arguments: request
and call_next
. The call_next
function passes the request to the next middleware or route handler.
Example:
from fastapi import FastAPI, Request app = FastAPI() @app.middleware("http") async def add_process_time_header(request: Request, call_next): start_time = time.time() response = await call_next(request) process_time = time.time() - start_time response.headers["X-Process-Time"] = str(process_time) return response
Request and Response Processing
Middleware can modify the request before it reaches the route handler. For example, you can add headers, log information, or authenticate the request. Similarly, it can modify the response before it is sent back to the client.
Example:
from fastapi import FastAPI, Request app = FastAPI() @app.middleware("http") async def authenticate_request(request: Request, call_next): if "Authorization" not in request.headers: return Response(status_code=401, content="Unauthorized") response = await call_next(request) return response
Order of Execution
The order in which middleware functions are added to the application determines their execution order. Middleware added first will be executed first, and so on.
Example:
from fastapi import FastAPI, Request app = FastAPI() @app.middleware("http") async def middleware_one(request: Request, call_next): print("Middleware One: Before") response = await call_next(request) print("Middleware One: After") return response @app.middleware("http") async def middleware_two(request: Request, call_next): print("Middleware Two: Before") response = await call_next(request) print("Middleware Two: After") return response
Analogies
Think of middleware as a series of checkpoints in a factory assembly line. Each checkpoint (middleware function) inspects and processes the product (request/response) before passing it to the next checkpoint. The order of checkpoints is crucial, as it determines the sequence of inspections and modifications.
Another analogy is a security guard at an office building. The guard (middleware) checks the visitor's credentials (request) before allowing them to enter the building (route handler). After the visitor leaves, the guard may also check the visitor's belongings (response) before they exit.
Conclusion
Middleware in FastAPI provides a flexible and powerful way to add global functionality to your application. By understanding how to define and order middleware functions, you can enhance your API with features like logging, authentication, and request/response modification.