FastAPI 进阶:中间件、依赖注入与 ORM

目录

一、中间件(Middleware)

什么是中间件?

中间件的作用

如何定义中间件

多个中间件的执行顺序

[二、依赖注入(Dependency Injection)](#二、依赖注入(Dependency Injection))

为什么需要依赖注入?

什么是依赖注入?

依赖注入的优势

依赖注入的应用场景

如何使用依赖注入

[中间件 vs 依赖注入](#中间件 vs 依赖注入)

三、ORM(对象关系映射)

[什么是 ORM?](#什么是 ORM?)

[ORM 的优势](#ORM 的优势)

[常见 ORM 工具](#常见 ORM 工具)

[ORM 使用流程](#ORM 使用流程)

实战示例

[1. 创建数据库引擎](#1. 创建数据库引擎)

[2. 定义模型类](#2. 定义模型类)

[3. 创建数据库表](#3. 创建数据库表)

[4. 在路由中使用 ORM](#4. 在路由中使用 ORM)

总结

FastAPI 作为 Python Web 框架,提供了强大的功能来构建高性能、易维护的 API 应用。

一、中间件(Middleware)

什么是中间件?

中间件是在每次请求进入 FastAPI 应用时都会被执行的函数。它在请求到达实际的路由处理函数之前运行,并且在响应返回给客户端之前再运行一次。

中间件的作用

中间件可以为每个请求添加统一的处理逻辑,常见应用场景包括:

  • ✅ 性能监控
  • ✅ 日志记录
  • ✅ 身份认证
  • ✅ 响应头处理
  • ✅ 跨域处理

如何定义中间件

在函数顶部使用装饰器 @app.middleware("http")

python 复制代码
@app.middleware("http")
async def middleware(request, call_next):
    print('中间件开始处理 -- start')
    response = await call_next(request)
    print('中间件处理完成 -- end')
    return response

多个中间件的执行顺序

多个中间件的执行顺序是自下而上的:

客户端 → 中间件 B → 中间件 A → 路由处理函数 → 中间件 A → 中间件 B → 客户端

二、依赖注入(Dependency Injection)

为什么需要依赖注入?

在开发过程中,我们经常会遇到多个接口需要相同参数或逻辑的情况:

python 复制代码
@app.get('/news/news_list')
async def get_news_list(
    skip: int = Query(0, ge=0),
    limit: int = Query(10, le=60)
):
    return {"list": "新闻列表"}

@app.get("/users/user_list")
async def get_user_list(
    skip: int = Query(0, ge=0),
    limit: int = Query(10, le=60)
):
    return {"users": "用户列表"}

这种重复代码不仅冗余,也难以维护。依赖注入系统就是用来解决这个问题的。

什么是依赖注入?

  • 依赖项:可重用的组件(函数/类),负责提供某种功能或数据
  • 注入:FastAPI 自动帮你调用依赖项,并将结果"注入"到路径操作函数中

依赖注入的优势

  1. 代码复用:一次编写,多处使用
  2. 解耦:业务逻辑与基础设施代码分离
  3. 易于测试:轻松地用模拟依赖替换真实依赖进行测试

依赖注入的应用场景

  • 从请求中提取和验证参数
  • 管理数据库会话的创建、使用、关闭
  • 抽取封装多个路由公用的逻辑代码
  • 验证用户身份、检查权限和角色要求等

如何使用依赖注入

步骤 1:创建依赖项

python 复制代码
async def common_parameters(
    skip: int = Query(0, ge=0),
    limit: int = Query(10, le=60)
):
    return {
        "skip": skip,
        "limit": limit
    }

步骤 2:导入并使用 Depends

python 复制代码
from fastapi import Depends

@app.get("/news/news_list")
async def get_news_list(
    commons = Depends(common_parameters)
):
    return commons

中间件 vs 依赖注入

|------|-----------|--------------|
| 特性 | 中间件 | 依赖注入 |
| 控制范围 | 所有人(所有请求) | 我说了算(可选择性使用) |
| 适用场景 | 全局统一处理 | 部分路由共享逻辑 |

三、ORM(对象关系映射)

什么是 ORM?

ORM(Object-Relational Mapping,对象关系映射)是一种编程技术,用于在面向对象编程语言和关系型数据库之间建立映射。它允许开发者通过操作对象的方式与数据库进行交互,而无需直接编写复杂的 SQL 语句。

ORM 的优势

  • ✅ 减少重复的 SQL 代码
  • ✅ 代码更简洁易读
  • ✅ 自动处理数据库连接和事务
  • ✅ 自动防止 SQL 注入攻击

常见 ORM 工具

|----|----------------|--------------|-------------------|
| 排名 | ORM 工具 | 特点 | 适应场景 |
| 1 | SQLAlchemy ORM | 功能最强、最灵活、企业级 | 各类 API、微服务、数据应用 |
| 2 | Django ORM | 封装好、上手快 | Django 项目、管理后台 |
| 3 | Tortoise ORM | 全异步 | 异步 Web 服务、高并发 API |

ORM 使用流程

  1. 安装依赖
    • sqlalchemy[asyncio]
    • aiomysql(异步数据库驱动)
  1. 建库、建表
    • run_sync(Base.metadata.create_all)
  1. 操作数据
    • 查询
    • 新增
    • 修改
    • 删除

实战示例

1. 创建数据库引擎
python 复制代码
from sqlalchemy.ext.asyncio import create_async_engine

ASYNC_DATABASE_URL = "mysql+aiomysql://root:123456@localhost:3306/fastapi_test?charset=utf8"

async_engine = create_async_engine(
    ASYNC_DATABASE_URL,
    echo=True,
    pool_size=10,
    max_overflow=20
)
2. 定义模型类
python 复制代码
from sqlalchemy.ext.declarative import DeclarativeBase
from sqlalchemy.orm import mapped_column, Mapped
from sqlalchemy import DateTime, String, func
from datetime import datetime

class Base(DeclarativeBase):
    create_time: Mapped[datetime] = mapped_column(
        DateTime, insert_default=func.now(), default=datetime.now, comment="创建时间"
    )
    update_time: Mapped[datetime] = mapped_column(
        DateTime, insert_default=func.now(), onupdate=func.now(), default=datetime.now, comment="修改时间"
    )

class User(Base):
    __tablename__ = "user"
    id: Mapped[int] = mapped_column(primary_key=True)
    username: Mapped[str] = mapped_column(String(255))
    password: Mapped[str] = mapped_column(String(255))
3. 创建数据库表
python 复制代码
async def create_tables():
    async with async_engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)

@app.on_event("startup")
async def startup_event():
    await create_tables()
4. 在路由中使用 ORM

创建异步会话工厂和依赖项:

python 复制代码
from sqlalchemy.ext.asyncio import async_sessionmaker, AsyncSession

AsyncSessionLocal = async_sessionmaker(
    bind=async_engine,
    class_=AsyncSession,
    expire_on_commit=False
)

async def get_database():
    async with AsyncSessionLocal() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()

查询数据:

python 复制代码
from sqlalchemy import select

@app.get("/users")
async def get_user_list(
    db: AsyncSession = Depends(get_database)
):
    result = await db.execute(select(User))
    users = result.scalars().all()
    return users

新增数据:

python 复制代码
@app.post("/users")
async def create_user(
    user: UserCreate,
    db: AsyncSession = Depends(get_database)
):
    db_user = User(username=user.username, password=user.password)
    db.add(db_user)
    await db.flush()
    return db_user

更新数据:

python 复制代码
@app.put("/users/{user_id}")
async def update_user(
    user_id: int,
    user_update: UserUpdate,
    db: AsyncSession = Depends(get_database)
):
    user = await db.get(User, user_id)
    if user:
        user.username = user_update.username
        user.password = user_update.password
    return user

删除数据:

python 复制代码
@app.delete("/users/{user_id}")
async def delete_user(
    user_id: int,
    db: AsyncSession = Depends(get_database)
):
    user = await db.get(User, user_id)
    if user:
        await db.delete(user)
    return {"message": "删除成功"}

总结

FastAPI 的这三个进阶特性各有所长:

  • 中间件:适合处理全局统一的请求/响应逻辑
  • 依赖注入:适合在部分路由间共享逻辑,灵活可控
  • ORM:让数据库操作变得面向对象,简洁安全

合理组合使用这三个特性,可以让你的 FastAPI 应用更加优雅、高效和易于维护!

相关推荐
高洁012 小时前
多模态大模型的统一表征与推理范式
人工智能·python·深度学习·机器学习·transformer
啊阿狸不会拉杆2 小时前
《计算机视觉:模型、学习和推理》第 8 章-回归模型
人工智能·python·学习·机器学习·计算机视觉·回归·回归模型
小鸡吃米…2 小时前
TensorFlow 优化器
人工智能·python·tensorflow
凌云拓界2 小时前
TypeWell全攻略(四):AI键位分析,让数据开口说话
前端·人工智能·后端·python·ai·交互
码界筑梦坊2 小时前
220-基于Python的诺贝尔奖数据可视化分析系统
开发语言·python·信息可视化·数据分析·毕业设计·fastapi
风轻扬7772 小时前
SqlAlchemy异步IO
python·异步io
27669582922 小时前
微博评论采集
开发语言·python·微博·微博评论·微博评论采集
我的xiaodoujiao2 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 51--CI/CD 4--推送本地代码到Git远程仓库
python·学习·测试工具·ci/cd·pytest
reasonsummer2 小时前
【办公类-109-10】20260228圆牌被子牌(接送卡&被子卡&床卡&入园卡_word编辑单面_添加有效期)
python·word