8.7 请求生命周期与中间件执行顺序
FastAPI 请求生命周期与中间件执行顺序 - 适合Python初学者的简单教程
本教程为Python初学者详细解释FastAPI中的请求生命周期和中间件执行顺序。通过生活化类比和动手实践,快速上手FastAPI Web开发,建立信心。
FastAPI 入门教程:请求生命周期与中间件执行顺序
引言
欢迎来到FastAPI入门教程!如果你有基础Python语法知识,但还没有Web开发经验,那么这个教程非常适合你。我们将从零开始,用生活化的例子来解释复杂的概念,并通过动手实践建立信心。
FastAPI是一个现代的、快速的Python Web框架,用于构建API。它易于学习,功能强大。
第一部分:请求生命周期 – 就像点外卖
想象一下,你正在点一份外卖。这个过程就是请求生命周期的一个好例子。
- 你下单:发送一个请求到餐厅(服务器)。
- 餐厅接收:服务器接收你的请求。
- 处理订单:服务器处理你的请求,比如检查菜单、准备食物。
- 送出食物:服务器发送响应给你。
- 你收到食物:你接收到响应。
在FastAPI中,一个HTTP请求也经历类似的阶段。当一个请求到达时,FastAPI会:
- 接收请求
- 路由到正确的处理函数(端点)
- 处理请求(运行你的代码)
- 生成响应
- 发送响应回客户端
动手实践:创建一个简单的请求
让我们来创建一个FastAPI应用,看看请求生命周期在行动。
首先,安装FastAPI和Uvicorn(一个ASGI服务器):
pip install fastapi uvicorn
然后,创建一个Python文件,比如 main.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def home():
return {"message": "Hello, World!"}
运行这个应用:
uvicorn main:app --reload
打开浏览器访问 http://127.0.0.1:8000/,你会看到 {"message": "Hello, World!"}。恭喜!你已经成功处理了一个请求的生命周期。
成功时刻:看到这个响应,你就已经理解了请求的基本流程!
第二部分:中间件 – 像餐厅里的员工
中间件是处理请求和响应的函数,它们可以在请求生命周期中的特定点被调用。用一个类比:在餐厅里,有不同的员工处理订单:
- 接单员:接收订单(中间件在请求开始时运行)。
- 厨师:准备食物(中间件在请求处理前运行)。
- 打包员:打包食物(中间件在响应发送前运行)。
每个员工都在特定阶段工作,并且他们的顺序很重要。例如,如果厨师先于接单员工作,那订单还没接收就被处理了,这没有意义。
在FastAPI中,你可以定义中间件来执行任务,比如日志记录、身份验证、修改请求或响应。
如何添加中间件
FastAPI使用ASGI中间件。一个简单的例子是添加一个日志中间件。
更新 main.py:
from fastapi import FastAPI
from fastapi.middleware.base import BaseHTTPMiddleware
app = FastAPI()
# 自定义一个简单的中间件
class SimpleMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# 在请求开始时记录
print(f"接收到请求: {request.url}")
# 调用下一个中间件或端点
response = await call_next(request)
# 在响应发送前记录
print(f"发送响应: {response.status_code}")
return response
app.add_middleware(SimpleMiddleware)
@app.get("/")
def home():
return {"message": "Hello, World!"}
运行应用,发送请求,你会在控制台看到日志输出。现在,你已经添加了一个中间件!
成功时刻:看到日志输出,你理解了中间件如何介入请求生命周期。
第三部分:中间件执行顺序 – 员工的工作顺序
当你有多个中间件时,它们的执行顺序很重要。FastAPI中,中间件按照它们添加的顺序执行。
用一个例子:假设你有两个中间件,一个记录请求开始,一个记录请求结束。添加的顺序决定了谁先执行。
更新 main.py 添加两个中间件:
from fastapi import FastAPI
from fastapi.middleware.base import BaseHTTPMiddleware
app = FastAPI()
# 第一个中间件:记录请求开始
class FirstMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
print("第一个中间件:请求开始")
response = await call_next(request)
print("第一个中间件:响应发送前")
return response
# 第二个中间件:记录请求详细信息
class SecondMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
print("第二个中间件:请求开始")
response = await call_next(request)
print("第二个中间件:响应发送前")
return response
app.add_middleware(FirstMiddleware)
app.add_middleware(SecondMiddleware)
@app.get("/")
def home():
return {"message": "Hello, World!"}
运行应用,发送请求。观察控制台输出:
第一个中间件:请求开始
第二个中间件:请求开始
第二个中间件:响应发送前
第一个中间件:响应发送前
注意:中间件的执行流程是,在请求阶段,中间件按添加顺序在调用 call_next 前执行(这表示它们按顺序介入请求),而在响应阶段,它们按添加顺序的逆序在 call_next 后执行。为了更清晰,可以修改中间件:
# 更新中间件以更清晰显示执行顺序
class FirstMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
print("第一个中间件:在 call_next 之前")
response = await call_next(request)
print("第一个中间件:在 call_next 之后")
return response
class SecondMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
print("第二个中间件:在 call_next 之前")
response = await call_next(request)
print("第二个中间件:在 call_next 之后")
return response
app.add_middleware(FirstMiddleware)
app.add_middleware(SecondMiddleware)
输出会是:
第一个中间件:在 call_next 之前
第二个中间件:在 call_next 之前
(端点执行并返回响应)
第二个中间件:在 call_next 之后
第一个中间件:在 call_next 之后
这展示了中间件如何嵌套执行:当第一个中间件调用 call_next 时,它会执行第二个中间件或端点,然后返回。
成功时刻:通过控制台输出,你直观地看到了中间件的执行顺序,并理解了它如何影响请求生命周期。
结论
你已经学习了FastAPI中请求生命周期的基本概念和中间件的执行顺序。通过简单的类比和动手实践,你建立了对Web开发的初步理解。
接下来,你可以尝试添加更多中间件,如错误处理或身份验证中间件,来扩展你的应用。
记住,实践是最好的学习方式。继续探索FastAPI的文档,构建更多的项目!