FastAPI 教程

8.7 请求生命周期与中间件执行顺序

FastAPI 请求生命周期与中间件执行顺序 - 适合Python初学者的简单教程

FastAPI 教程

本教程为Python初学者详细解释FastAPI中的请求生命周期和中间件执行顺序。通过生活化类比和动手实践,快速上手FastAPI Web开发,建立信心。

推荐工具
PyCharm专业版开发必备

功能强大的Python IDE,提供智能代码补全、代码分析、调试和测试工具,提高Python开发效率。特别适合处理列表等数据结构的开发工作。

了解更多

FastAPI 入门教程:请求生命周期与中间件执行顺序

引言

欢迎来到FastAPI入门教程!如果你有基础Python语法知识,但还没有Web开发经验,那么这个教程非常适合你。我们将从零开始,用生活化的例子来解释复杂的概念,并通过动手实践建立信心。

FastAPI是一个现代的、快速的Python Web框架,用于构建API。它易于学习,功能强大。

第一部分:请求生命周期 – 就像点外卖

想象一下,你正在点一份外卖。这个过程就是请求生命周期的一个好例子。

  • 你下单:发送一个请求到餐厅(服务器)。
  • 餐厅接收:服务器接收你的请求。
  • 处理订单:服务器处理你的请求,比如检查菜单、准备食物。
  • 送出食物:服务器发送响应给你。
  • 你收到食物:你接收到响应。

在FastAPI中,一个HTTP请求也经历类似的阶段。当一个请求到达时,FastAPI会:

  1. 接收请求
  2. 路由到正确的处理函数(端点)
  3. 处理请求(运行你的代码)
  4. 生成响应
  5. 发送响应回客户端

动手实践:创建一个简单的请求

让我们来创建一个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的文档,构建更多的项目!

开发工具推荐
Python开发者工具包

包含虚拟环境管理、代码格式化、依赖管理、测试框架等Python开发全流程工具,提高开发效率。特别适合处理复杂数据结构和算法。

获取工具包