前言FastAPI 作为高性能的异步 Web 框架凭借简洁的语法、自动的接口文档和优秀的性能成为 Python Web 开发的热门选择。入门之后想要开发企业级的 Web 应用还需要掌握中间件、依赖注入和ORM三大核心进阶特性 —— 它们能帮我们实现代码复用、逻辑解耦让数据库操作更优雅大幅提升项目的可维护性和扩展性。1. 中间件统一处理所有请求的利器1.1 中间件的核心应用场景中间件的设计初衷是为所有接口添加通用处理逻辑无需在每个路由中重复编写。典型场景包括全局用户身份认证、权限校验接口请求 / 响应日志记录、性能监控跨域请求处理CORS、统一设置响应头全局异常捕获与处理1.2 中间件的定义与基本使用定义中间件需使用app.middleware(http)装饰器函数为异步类型接收request请求对象和call_next调用下一个中间件 / 路由处理函数的方法两个参数最终返回响应对象。from fastapi import FastAPI app FastAPI() # 定义基础中间件 app.middleware(http) # async异步处理协程 async def global_middleware(request, call_next): # request请求cell_next下一个中间件或路由处理函数 # 请求到达路由前执行start部分 print(f中间件开始处理{request.method} {request.url}) # 传递请求到下一个中间件/路由 response await call_next(request) # 响应返回客户端前执行end部分 print(f中间件处理完成响应状态码 {response.status_code}) return response app.get(/) async def root(): return {message: Hello FastAPI}1.3 多个中间件的执行顺序FastAPI 中注册多个中间件时start 部分按注册逆序执行end 部分按注册顺序执行自下而上执行 start自上而下执行 end可以理解为 “洋葱模型”—— 请求从外层穿透到内层路由响应从内层穿透回外层客户端。from fastapi import FastAPI app FastAPI() # 中间件2 app.middleware(http) async def middleware2(request, call_next): print(middleware2 start) # 第一步执行打印这行 # 第二步执行调用 call_next(request) # 此时 call_next 的作用是把请求传递给下一个中间件middleware1 response await call_next(request) print(middleware2 end) # 第六步执行打印这行 return response # 第七步返回最终的响应 # 中间件1 app.middleware(http) async def middleware1(request, call_next): print(middleware1 start) # 第三步执行打印这行 # 第四步执行调用 call_next(request) # 此时 call_next 的作用是把请求传递给最终的路由处理函数比如你的 / 接口 response await call_next(request) print(middleware1 end) # 第五步执行打印这行 return response # 把路由返回的 response 传回 middleware2 # 访问这个根路由 app.get(/) async def root(): print(路由函数执行) # 第四步中间执行打印这行 return {message: Hello FastAPI} # 返回响应 # 访问/时控制台输出顺序 # middleware2 start → middleware1 start → 路由函数执行 → middleware1 end → middleware2 end1.4 中间件的核心特点全局生效控制所有请求和响应无需手动调用异步执行基于协程不阻塞主线程符合 FastAPI 的异步设计责任单一一个中间件实现一个通用逻辑便于维护2.依赖注入抽离通用逻辑实现代码复用如果说中间件是 “全局无差别处理”那么依赖注入就是精细化的通用逻辑复用—— 可以自定义哪些路由使用通用逻辑完美解决多个接口重复编写相同代码的问题如分页参数、数据库连接、局部权限校验。2.1 依赖注入的核心概念依赖项可重用的组件函数 / 类负责提供某种功能或数据如分页参数解析、数据库会话创建注入FastAPI 自动调用依赖项并将执行结果传递到路由处理函数中无需手动调用核心优势代码复用、逻辑解耦、易于测试可轻松替换模拟依赖无需修改业务代码依赖注入的典型应用场景抽取多个路由的通用参数如分页的skip/limit、排序参数共享数据库连接 / 会话管理创建、使用、关闭局部接口的身份认证、权限检查非全局从请求中提取和验证自定义参数路径、查询、请求体2.2 依赖注入的实战使用以分页参数复用为例这是开发中最常见的场景多个接口都需要skip跳过条数和limit返回条数参数通过依赖注入可一次性实现多处调用。步骤一创建依赖项通用逻辑函数from fastapi import Query # 分页参数逻辑共用新闻列表和用户列表 # 1.依赖项 # 定义分页参数依赖项 async def common_page_parameters( skip: int Query(0, ge0, description跳过的记录数), limit: int Query(10, le100, description返回的记录数最大100) ): return {skip: skip, limit: limit}步骤 2导入 Depends在路由中声明依赖from fastapi import FastAPI, Depends #2.导入Depends app FastAPI() # 新闻列表接口使用分页依赖 app.get(/news/list) async def get_news_list(commons Depends(common_page_parameters)): # 直接使用依赖项返回的分页参数 return {message: 新闻列表, **commons} # 用户列表接口复用同一个分页依赖 app.get(/users/list) async def get_user_list(commons Depends(common_page_parameters)): return {message: 用户列表, **commons}完整代码from fastapi import FastAPI,Query,Depends app FastAPI() # 定义分页参数依赖项 async def common_page_parameters( skip: int Query(0, ge0, description跳过的记录数), limit: int Query(10, le100, description返回的记录数最大100) ): return {skip: skip, limit: limit} # 新闻列表接口使用分页依赖 app.get(/news/list) async def get_news_list(commons Depends(common_page_parameters)): # 直接使用依赖项返回的分页参数 return {message: 新闻列表, **commons} # 用户列表接口复用同一个分页依赖 app.get(/users/list) async def get_user_list(commons Depends(common_page_parameters)): return {message: 用户列表, **commons}3.中间件与依赖注入的核心区别很多开发者会混淆两者的使用场景核心区别在于作用范围和灵活性简单来说所有接口都需要的逻辑用中间件部分接口需要的逻辑用依赖注入。
FastAPI进阶:中间件全局拦截、依赖注入与请求生命周期管理
前言FastAPI 作为高性能的异步 Web 框架凭借简洁的语法、自动的接口文档和优秀的性能成为 Python Web 开发的热门选择。入门之后想要开发企业级的 Web 应用还需要掌握中间件、依赖注入和ORM三大核心进阶特性 —— 它们能帮我们实现代码复用、逻辑解耦让数据库操作更优雅大幅提升项目的可维护性和扩展性。1. 中间件统一处理所有请求的利器1.1 中间件的核心应用场景中间件的设计初衷是为所有接口添加通用处理逻辑无需在每个路由中重复编写。典型场景包括全局用户身份认证、权限校验接口请求 / 响应日志记录、性能监控跨域请求处理CORS、统一设置响应头全局异常捕获与处理1.2 中间件的定义与基本使用定义中间件需使用app.middleware(http)装饰器函数为异步类型接收request请求对象和call_next调用下一个中间件 / 路由处理函数的方法两个参数最终返回响应对象。from fastapi import FastAPI app FastAPI() # 定义基础中间件 app.middleware(http) # async异步处理协程 async def global_middleware(request, call_next): # request请求cell_next下一个中间件或路由处理函数 # 请求到达路由前执行start部分 print(f中间件开始处理{request.method} {request.url}) # 传递请求到下一个中间件/路由 response await call_next(request) # 响应返回客户端前执行end部分 print(f中间件处理完成响应状态码 {response.status_code}) return response app.get(/) async def root(): return {message: Hello FastAPI}1.3 多个中间件的执行顺序FastAPI 中注册多个中间件时start 部分按注册逆序执行end 部分按注册顺序执行自下而上执行 start自上而下执行 end可以理解为 “洋葱模型”—— 请求从外层穿透到内层路由响应从内层穿透回外层客户端。from fastapi import FastAPI app FastAPI() # 中间件2 app.middleware(http) async def middleware2(request, call_next): print(middleware2 start) # 第一步执行打印这行 # 第二步执行调用 call_next(request) # 此时 call_next 的作用是把请求传递给下一个中间件middleware1 response await call_next(request) print(middleware2 end) # 第六步执行打印这行 return response # 第七步返回最终的响应 # 中间件1 app.middleware(http) async def middleware1(request, call_next): print(middleware1 start) # 第三步执行打印这行 # 第四步执行调用 call_next(request) # 此时 call_next 的作用是把请求传递给最终的路由处理函数比如你的 / 接口 response await call_next(request) print(middleware1 end) # 第五步执行打印这行 return response # 把路由返回的 response 传回 middleware2 # 访问这个根路由 app.get(/) async def root(): print(路由函数执行) # 第四步中间执行打印这行 return {message: Hello FastAPI} # 返回响应 # 访问/时控制台输出顺序 # middleware2 start → middleware1 start → 路由函数执行 → middleware1 end → middleware2 end1.4 中间件的核心特点全局生效控制所有请求和响应无需手动调用异步执行基于协程不阻塞主线程符合 FastAPI 的异步设计责任单一一个中间件实现一个通用逻辑便于维护2.依赖注入抽离通用逻辑实现代码复用如果说中间件是 “全局无差别处理”那么依赖注入就是精细化的通用逻辑复用—— 可以自定义哪些路由使用通用逻辑完美解决多个接口重复编写相同代码的问题如分页参数、数据库连接、局部权限校验。2.1 依赖注入的核心概念依赖项可重用的组件函数 / 类负责提供某种功能或数据如分页参数解析、数据库会话创建注入FastAPI 自动调用依赖项并将执行结果传递到路由处理函数中无需手动调用核心优势代码复用、逻辑解耦、易于测试可轻松替换模拟依赖无需修改业务代码依赖注入的典型应用场景抽取多个路由的通用参数如分页的skip/limit、排序参数共享数据库连接 / 会话管理创建、使用、关闭局部接口的身份认证、权限检查非全局从请求中提取和验证自定义参数路径、查询、请求体2.2 依赖注入的实战使用以分页参数复用为例这是开发中最常见的场景多个接口都需要skip跳过条数和limit返回条数参数通过依赖注入可一次性实现多处调用。步骤一创建依赖项通用逻辑函数from fastapi import Query # 分页参数逻辑共用新闻列表和用户列表 # 1.依赖项 # 定义分页参数依赖项 async def common_page_parameters( skip: int Query(0, ge0, description跳过的记录数), limit: int Query(10, le100, description返回的记录数最大100) ): return {skip: skip, limit: limit}步骤 2导入 Depends在路由中声明依赖from fastapi import FastAPI, Depends #2.导入Depends app FastAPI() # 新闻列表接口使用分页依赖 app.get(/news/list) async def get_news_list(commons Depends(common_page_parameters)): # 直接使用依赖项返回的分页参数 return {message: 新闻列表, **commons} # 用户列表接口复用同一个分页依赖 app.get(/users/list) async def get_user_list(commons Depends(common_page_parameters)): return {message: 用户列表, **commons}完整代码from fastapi import FastAPI,Query,Depends app FastAPI() # 定义分页参数依赖项 async def common_page_parameters( skip: int Query(0, ge0, description跳过的记录数), limit: int Query(10, le100, description返回的记录数最大100) ): return {skip: skip, limit: limit} # 新闻列表接口使用分页依赖 app.get(/news/list) async def get_news_list(commons Depends(common_page_parameters)): # 直接使用依赖项返回的分页参数 return {message: 新闻列表, **commons} # 用户列表接口复用同一个分页依赖 app.get(/users/list) async def get_user_list(commons Depends(common_page_parameters)): return {message: 用户列表, **commons}3.中间件与依赖注入的核心区别很多开发者会混淆两者的使用场景核心区别在于作用范围和灵活性简单来说所有接口都需要的逻辑用中间件部分接口需要的逻辑用依赖注入。