1:中间件(Middleware)
python
# 添加一个中间件来记录所有请求
@app.middleware("http")
async def log_requests(request: Request, call_next):
logger.info(f"收到请求: {request.method} {request.url}")
try:
# 前置处理
print("Before request")
response = await call_next(request)
logger.info(f"响应状态: {response.status_code}")
# 后置处理
print("After request")
return response
except Exception as e:
logger.error(f"处理请求时发生错误: {e}")
raise
2:依赖注入系统(Dependencies),可以创建可重用的依赖来实现横切关注点:
2-1:例子一
python
from fastapi import Depends, Request
async def common_dependency(request: Request):
print("Common logic for all endpoints")
return {"user_id": 123}
@app.get("/")
async def root(common: dict = Depends(common_dependency)):
return {"message": "Welcome"}
@app.post("/items")
async def create_item(common: dict = Depends(common_dependency)):
return {"item_id": 1}
2-2:例子二
python
from fastapi import Depends
import asyncio
# 1. 定义「切面逻辑」的依赖函数(可同步/异步)
async def method_common_dependency():
"""方法级通用切面:前置校验、资源初始化等"""
print("方法执行前的切面逻辑:检查权限/初始化资源")
# 模拟耗时操作(如查数据库、调用第三方服务)
await asyncio.sleep(0.1)
# 返回需要注入到方法的上下文数据
return {"trace_id": "abc-123", "timestamp": 1735689600}
# 2. 普通方法(非 HTTP 接口)使用 Depends 注入切面逻辑
async def business_method_1(
param1: str,
# 注入切面依赖(和路由用法完全一致)
common_ctx: dict = Depends(method_common_dependency)
):
print(f" 执行业务方法1,参数:{param1},上下文:{common_ctx}")
return {"result": f"success_{param1}", "trace_id": common_ctx["trace_id"]}
async def business_method_2(
param2: int,
common_ctx: dict = Depends(method_common_dependency)
):
print(f" 执行业务方法2,参数:{param2},上下文:{common_ctx}")
return {"result": param2 * 10, "trace_id": common_ctx["trace_id"]}
# 3. 测试调用
async def main():
res1 = await business_method_1("test")
res2 = await business_method_2(5)
print("最终结果:", res1, res2)
asyncio.run(main())
3:路由器级别的中间件,可以为特定的路由器添加中间件:
python
# 在 auth/router.py 中
router = APIRouter()
@router.middleware("http")
async def auth_middleware(request: Request, call_next):
# 只应用于 auth 路由器下的所有端点
print("Auth specific middleware")
response = await call_next(request)
return response
4: 装饰器模式,创建自定义装饰器来包装路由函数:
python
from functools import wraps
def log_calls(func):
@wraps(func)
async def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
result = await func(*args, **kwargs)
print(f"Finished {func.__name__}")
return result
return wrapper
@app.get("/")
@log_calls
async def root():
return {"message": "Welcome"}
5:事件处理器,FastAPI 提供了应用级别的事件处理器:
python
@app.on_event("startup")
async def startup_event():
# 应用启动时执行
pass
@app.on_event("shutdown")
async def shutdown_event():
# 应用关闭时执行
pass