FastAPI中类似面向切面编程(python)

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
相关推荐
许杰小刀31 分钟前
FastAPI + Vue 前后端分离实战:我的项目结构“避坑指南”
前端·vue.js·fastapi
Aric_Jones9 小时前
从实战理解异步、并发并行与GIL:FastAPI vs SpringBoot
java·spring boot·fastapi
不是株11 小时前
FastAPI
python·fastapi
星星也在雾里11 小时前
Dify + FastAPI + 讯飞WebSocket实现方言识别
人工智能·fastapi
Ares-Wang1 天前
FastAPI 数据验证 Pydantic Flask 用 WTForms
python·flask·fastapi
曲幽1 天前
FastAPI自动生成的API文档太丑?我花了一晚上把它改成了客户愿意付费的样子
python·fastapi·web·swagger·openapi·scalar·docs
PieroPc2 天前
一个功能强大的 Web 端标签设计和打印工具,支持服务器端直接打印到局域网打印机。Fastapi + html
前端·html·fastapi
别抢我的锅包肉2 天前
FastAPI + Vue3 + Vite 跨域报错全解:从 `Access-Control-Allow-Origin missing` 到彻底修复
中间件·状态模式·fastapi
Chase_______2 天前
【FastAPI】内网/离线环境docs文档无法显示的解决方案
fastapi
小李云雾2 天前
FastAPI 后端开发:文件上传 + 表单提交
开发语言·python·lua·postman·fastapi