中间件与依赖系统:构建高效 Web 后端的双重利器
2026/5/11 1:25:34 网站建设 项目流程

文章目录

  • 一、 中间件(Middleware):全局的“拦截器”
    • 1.1 核心概念
    • 1.2 执行原理
    • 1.3 代码实现
    • 1.4 多中间件执行顺序
  • 二、 依赖系统(Dependency Injection):精细化的“业务注入”
    • 2.1 为什么要用依赖系统?
    • 2.2 如何实现依赖?
  • 三、如何实现“局部中间件”?
  • 四、 注意注意注意注意注意

一、 中间件(Middleware):全局的“拦截器”

1.1 核心概念

中间件是一个在每个 请求 (Request) 被处理之前,以及每个 响应 (Response) 返回之前运行的函数。它是全局性的,一旦建立,项目中的所有路由都会经过它。

1.2 执行原理

中间件通过call_next建立起请求的传递链:
1、前置处理:请求向下传递(交给路由)之前执行。
2、传递请求:调用await call_next(request)
3、后置处理:路由处理完后,在响应返回给客户端之前执行。

1.3 代码实现

在 main.py 中直接定义(注意:APIRouter 不支持直接定义中间件):

@app.middleware("http")asyncdefprocess_timer(request:Request,call_next):# 【前置】记录请求开始时间print("中间件:开始拦截请求")response=awaitcall_next(request)# 【后置】添加自定义响应头或日志print("中间件:准备返回结果")returnresponse

1.4 多中间件执行顺序

当有多个中间件时,执行顺序是从下向上(或者说后定义的先执行请求,先定义的后处理响应)。

二、 依赖系统(Dependency Injection):精细化的“业务注入”

2.1 为什么要用依赖系统?

如果说中间件是“强迫所有人过安检”,那么依赖系统就是“谁需要谁申请”。
假设你写了两个接口:一个是“查看个人资料”,一个是“修改个人资料”。这两个接口都需要先验证用户是否登录。
这时候,你写一个验证函数作为“依赖项”,谁需要验证,谁就在参数里“领取”它。

2.2 如何实现依赖?

# 1. 定义一个依赖项asyncdefverify_token(token:str):iftoken!="secret-key":return{"error":"暗号不对,不准入内"}return"验证通过"# 2. 在需要的路由里“领取”它@user_router.get("/info/")asyncdefget_user_info(auth_status=Depends(verify_token)):# 只有 verify_token 成功了,才会执行这里return{"status":auth_status,"name":"Chang Yang"}

三、如何实现“局部中间件”?

中间件一旦建立,所有路由都得走,能不能让某些路由走,某些不走?
答案是:当然能!!!

在 FastAPI 里,这通常有两种实现方案:

  • Plan A:在中间件内部做排除(白名单)
    在中间件函数里加个判断:
@app.middleware("http")asyncdefselective_middleware(request:Request,call_next):# 定义不需要走中间件的路径white_list=["/login","/register","/docs"]ifrequest.url.pathinwhite_list:returnawaitcall_next(request)# 直接放行,不走下面的逻辑# 下面是正常的拦截逻辑...print("正在拦截受保护的路径")returnawaitcall_next(request)
  • Plan B:使用“依赖注入”模拟局部中间件
    部分代码示例(这里是一个单独的py文件):
importtime# 用依赖系统上实现局部中间件# 第一步:定义一个依赖函数asyncdefmy_timer_dep():start_time=time.time()yieldprocess_time=time.time()-start_timeprint("接口耗时:",process_time,"秒")
fromfastapiimportDepends# 导入依赖函数fromaps.Common.depsimportmy_timer_dep@api_router.get('/{id}',dependencies=[Depends(my_timer_dep)])asyncdefget_user(id:int):return{'id':id,'name':'张三'}

四、 注意注意注意注意注意

  • 路径斜杠问题:在定义带有查询参数的路径时,结尾建议加上 /。虽然某些 AI 或文档说不加也能跑,但在标准 RESTful 实践和 FastAPI 的某些配置下,加斜杠能避免不必要的重定向问题。
  • 异步避坑:如果你在中间件里处理文件或耗时 I/O,一定要记得使用 await,否则会阻塞整个异步循环。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询