8.2 创建自定义中间件
FastAPI 自定义中间件:Python 初学者快速入门教程
本教程面向有Python语法基础的初学者,教你如何在FastAPI中轻松创建自定义中间件。通过生活化类比、简单步骤和实践示例,快速上手Web开发,建立信心。
FastAPI 自定义中间件:Python 初学者快速入门
欢迎!如果你有基础Python知识,但从未接触过Web开发,别担心。本教程将带你轻松创建自定义中间件,就像玩积木一样简单。我们会用简单易懂的语言和生活化类比,让你在几分钟内就能看到成果,享受Web开发的乐趣。
什么是中间件?用生活化类比来理解
想象一下邮局系统:当邮件被发送时,它必须经过多个处理步骤。比如,邮局的分拣员会检查邮件的地址、贴上标签,然后分发给不同的区域。在Web开发中,中间件就是邮局的分拣员——它处理所有进出你的Web应用(比如FastAPI)的请求和响应。每个中间件都可以在请求到达应用之前或响应返回给用户之后执行一些操作,比如记录日志、检查认证或添加额外信息。
为什么要创建自定义中间件?
默认情况下,FastAPI 会处理基本的路由和响应,但有时你需要一些额外功能,比如:
- 记录日志:自动记录每个请求的时间、方法等信息,方便调试。
- 身份验证:检查用户是否已登录,保护敏感数据。
- 添加头部信息:如跨域资源共享(CORS)设置。 创建自定义中间件让你可以定制这些功能,完全掌控你的应用。
开始前的准备:快速设置环境
你需要有Python基础知识,并确保安装了Python(建议Python 3.6+)。如果你还没有,可以从python.org下载。然后,安装FastAPI和Uvicorn(一个Web服务器)。
打开终端(命令行),运行:
pip install fastapi uvicorn
现在,你已经准备好了一切——就像有了邮局的分拣员工具箱!
第一步:创建最简单的日志中间件(你的第一个成功时刻)
让我们从一个超级简单的例子开始:创建一个中间件,在每次请求时打印一条消息到控制台。成功时,你会看到控制台输出,证明你的中间件正在工作。
- 创建文件:新建一个名为
main.py的文件,用你喜欢的编辑器打开(如VS Code或Notepad++)。 - 编写代码:将以下代码复制到
main.py中。
from fastapi import FastAPI, Request
import time # 导入时间模块,用于记录时间
app = FastAPI() # 创建一个FastAPI应用,就像盖一个邮局大楼
# 定义我们的自定义中间件函数
@app.middleware("http") # 告诉FastAPI这是一个HTTP中间件
async def simple_log_middleware(request: Request, call_next):
# 请求到达前的处理:记录开始时间
start_time = time.time()
print(f"🚀 请求开始: {request.method} {request.url}") # 打印请求信息
# 将请求传递给下一个处理程序(比如其他中间件或路由)
response = await call_next(request)
# 响应返回后的处理:计算处理时间并打印
process_time = time.time() - start_time
print(f"✅ 请求完成: {request.method} {request.url} 耗时 {process_time:.2f} 秒")
return response # 返回响应,就像分拣员将邮件送出去
# 添加一个简单的路由来测试
@app.get("/")
async def home():
return {"message": "欢迎来到我的FastAPI应用!你的中间件正在工作。"}
- 运行应用:在终端中,切换到
main.py所在目录,运行:
uvicorn main:app --reload
--reload 参数让服务器在代码更改时自动重启,方便调试。你会看到输出,表示服务器已启动。
- 测试成功:打开浏览器,访问
http://127.0.0.1:8000。在控制台,你应该立即看到类似这样的输出:
🚀 请求开始: GET http://127.0.0.1:8000/
✅ 请求完成: GET http://127.0.0.1:8000/ 耗时 0.01 秒
恭喜! 你刚刚创建了第一个自定义中间件。这就是你的“成功时刻”——亲眼看到代码在工作,就像邮局分拣员在默默记录所有邮件一样。
第二步:扩展中间件功能——添加请求计数
现在,让我们增强它,让它更实用:添加一个计数器,记录总共处理了多少个请求。这类似于邮局的分拣员统计今天处理了多少邮件。
修改 main.py 中的代码:
from fastapi import FastAPI, Request
import time
app = FastAPI()
# 初始化一个计数器变量
request_count = 0
@app.middleware("http")
async def enhanced_log_middleware(request: Request, call_next):
global request_count # 声明使用全局变量,这样计数器可以跨请求保持
start_time = time.time()
print(f"🚀 请求开始: {request.method} {request.url}")
response = await call_next(request)
process_time = time.time() - start_time
request_count += 1 # 每次请求后增加计数
print(f"✅ 请求完成: {request.method} {request.url} 耗时 {process_time:.2f} 秒")
print(f"📊 总请求数: {request_count}") # 打印当前请求总数
return response
@app.get("/")
async def home():
return {"message": "计数器已激活,刷新页面查看请求数变化!"}
保存文件,由于使用了 --reload,服务器会自动重启。现在,访问 http://127.0.0.1:8000 多次,控制台会显示不断增加的总请求数。例如:
📊 总请求数: 1
📊 总请求数: 2
又一个成功时刻! 你不仅记录了日志,还添加了统计功能。这就像邮局分拣员现在不仅能检查邮件,还能报告工作总量,非常有用。
常见问题与注意事项
- 为什么使用
async def? FastAPI 支持异步操作,这能让应用处理更多请求而不会阻塞。作为初学者,可以简单理解为“这能让代码更高效”,后续可以深入学习异步编程。 - 中间件可以做什么? 除了日志和计数,还可以验证token(保护数据)、修改请求头、处理错误等。例如,你可以添加认证中间件来检查用户是否登录,就像邮局分拣员只处理有正确地址的邮件。
- 错误处理:如果在中间件中出现错误,FastAPI 会自动处理并返回错误响应,你可以自定义错误消息。
总结与鼓励
你已经学会了在FastAPI中创建自定义中间件的基础。整个过程就像邮局系统:先建一个邮局(FastAPI应用),然后雇佣分拣员(自定义中间件)来处理邮件。
下一步建议:
- 尝试添加更多功能,比如检查特定请求头或模拟用户认证。
- 探索FastAPI官方文档的中间件部分,了解更多高级用法。
- 在实践中学习——创建一个小型Web应用,集成这些中间件。
记住,Web开发并不可怕。通过动手实践,你已经迈出了第一步,建立了信心。继续享受编码的乐趣,祝你学习顺利!
本教程旨在帮助初学者轻松入门。如果你有任何问题,欢迎查阅FastAPI社区或在线搜索更多资源。Happy coding!