什么是FastAPI 框架的中间件(Middleware),与依赖(Dependencies)的区别

1. 中间件的概念

FastAPI 里,中间件(Middleware)是一个 在每次请求到达路由处理函数之前响应返回给客户端之前 执行的函数。

它相当于一个“拦截器”或“过滤器”,可以用来:

  • 在请求进入时做一些预处理(如日志、鉴权、限流等)

  • 在响应返回时做一些加工(如数据加密、统一格式化、添加响应头等)

简单理解:

客户端 → (请求预处理) → 路由函数 → (响应后处理) → 客户端

2. 工作原理

FastAPI 的中间件基于 Starlette,它是 ASGI(异步服务器网关接口)的一个实现。

中间件会包裹你的应用,形成一个“洋葱模型”:

请求进入
   ↓
中间件A(请求处理部分)
   ↓
中间件B(请求处理部分)
   ↓
路由处理函数(业务逻辑)
   ↓
中间件B(响应处理部分)
   ↓
中间件A(响应处理部分)
   ↓
响应返回

3. 中间件的编写方式

3.1 使用 @app.middleware 装饰器

最常见方式,直接注册一个异步函数:

from fastapi import FastAPI, Request
import time

app = FastAPI()

@app.middleware("http")  # 声明这是一个 HTTP 中间件
async def log_requests(request: Request, call_next):
    start_time = time.time()

    # 请求前处理
    print(f"请求路径: {request.url.path}")
    
    response = await call_next(request)  # 继续执行下一个中间件或路由处理函数

    # 响应后处理
    duration = time.time() - start_time
    print(f"处理时间: {duration:.4f}秒")
    response.headers["X-Process-Time"] = str(duration)
    
    return response

说明:

  • request:FastAPI 的请求对象

  • call_next:调用下一个中间件或实际的路由处理函数

  • 必须返回 response

3.2 使用类继承 BaseHTTPMiddleware

当中间件逻辑复杂时,更推荐这种方式,因为它支持更灵活的初始化。

from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware

app = FastAPI()

class CustomHeaderMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # 请求前
        print("进入中间件:添加自定义响应头")

        response = await call_next(request)

        # 响应后
        response.headers["X-Custom-Header"] = "Hello Middleware"
        return response

# 添加中间件
app.add_middleware(CustomHeaderMiddleware)

4. 常见中间件功能场景

场景描述示例
日志记录记录请求的路径、方法、耗时等print(f"{request.method} {request.url.path}")
统一响应格式把所有返回数据包装成统一 JSON 格式{"code": 0, "data": ..., "msg": "success"}
跨域处理CORS(跨域资源共享)from fastapi.middleware.cors import CORSMiddleware
请求限流限制访问频率,防止接口被刷用 Redis 存储 IP 访问次数
权限校验在进入路由前验证 Token解析 JWT 令牌
响应压缩压缩数据传输量(GZip、Brotli)from fastapi.middleware.gzip import GZipMiddleware
安全过滤过滤 XSS、SQL 注入等特殊字符正则替换或白名单过滤


5. FastAPI 内置常用中间件

FastAPI/Starlette 已经自带一些常用中间件,可以直接 app.add_middleware 使用:

5.1 跨域中间件

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 允许的源
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

5.2 GZip 压缩中间件

from fastapi.middleware.gzip import GZipMiddleware

app.add_middleware(GZipMiddleware, minimum_size=1000)  # 超过 1000 字节才压缩

6. 中间件 vs 依赖(Dependencies)

对比项中间件依赖(Depends)
作用范围全局(所有路由)可作用于单个路由或全局
执行顺序在路由处理函数前后路由执行前(依赖结束就结束)
适用场景日志、跨域、统一响应参数校验、权限控制、业务逻辑复用


总结

  • 中间件是全局拦截器,请求和响应都会经过它

  • 简单逻辑用 @app.middleware,复杂逻辑用 BaseHTTPMiddleware

  • 常用场景包括日志、跨域、统一响应、限流、权限等

  • 内置中间件(CORS、GZip)可以直接用,复杂需求可自定义

### FastAPI 框架Python 源码实现 FastAPI 是基于 Starlette 和 Pydantic 构建的一个高性能 Web 框架,它的源码托管在 GitHub 上,开发者可以通过访问其官方仓库来获取完整的源码并研究其实现细节[^1]。 #### 官方源码地址 FastAPI 的源码位于以下链接: [https://github.com/tiangolo/fastapi](https://github.com/tiangolo/fastapi) #### 主要模块结构分析 以下是 FastAPI 源码中的主要模块及其功能概述: 1. **`fastapi/applications.py`** - 这是 FastAPI 应用程序的核心入口文件。它定义了 `FastAPI` 类,该类继承自 Starlette 的 `Starlette` 类,并扩展了一些额外的功能,比如依赖注入支持和 OpenAPI 文档生成。 2. **`fastapi/routing.py`** - 此模块实现了路由机制,负责处理 URL 路径匹配、HTTP 方法解析以及调用相应的视图函数。它是 FastAPI 中路径操作的基础组件[^1]。 3. **`fastapi/dependencies/utils.py`** - 提供了用于管理依赖项注入的支持方法。通过这些工具,可以轻松实现复杂的参数传递逻辑而无需手动编写大量代码。 4. **`fastapi/schema/` 文件夹** - 包含了一系列数据验证相关的类和函数,它们利用 Pydantic 来完成输入输出的数据校验工作。这使得开发人员能够专注于业务逻辑而不是繁琐的手动检查过程。 5. **`fastapi/openapi/` 文件夹** - 自动化生成 Swagger UI 或 ReDoc 风格 API 文档的关键部分就在这里实现。通过对应用程序内部元信息的扫描,它可以动态构建符合 OpenAPI 标准的描述文档。 6. **中间件 (Middleware) 支持** - 在 `starlette/middleware/*` 下提供了多种内置中间件选项(如 CORS 处理),同时也允许用户注册自己的定制版本以满足特定需求。 7. **异常处理器** - 当发生错误时,默认会返回标准化 JSON 响应格式;如果希望调整这种行为,则可以在项目初始化阶段重新定义全局范围内的异常捕获策略。 #### 如何深入理解其实现? 为了更好地学习 FastAPI 的底层原理,建议按照如下方式逐步探索: - 浏览顶层目录下的 README.md 获取整体介绍; - 查看测试用例 (`tests/`) 学习如何正确使用各项特性; - 结合具体场景阅读对应子系统的源代码片段加深印象。 下面展示了一个简单的例子演示如何创建基本的应用实例并通过命令行运行服务: ```python from fastapi import FastAPI, Depends app = FastAPI() def common_parameters(q: str | None = None): return {"q": q} @app.get("/items/") async def read_items(commons: dict = Depends(common_parameters)): return commons ``` 此脚本展示了最基本的 GET 请求处理流程以及简单形式的依赖注入实践。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值