Python Web 开发:FastAPI 依赖注入与中间件应用

Python Web 开发:FastAPI 依赖注入与中间件应用

目录
  1. 🧩 FastAPI 中的依赖注入
  2. ⚙️ 中间件概述与常见应用
    • 🛠️ CORS 中间件
    • 📝 请求日志中间件
    • ⏱️ 请求处理时间中间件
    • ⚠️ 异常捕获中间件

1. 🧩 FastAPI 中的依赖注入

FastAPI 强大的依赖注入机制使得开发者能够在处理 HTTP 请求时,解耦业务逻辑并提高代码可维护性。依赖注入(DI)是将外部组件注入到当前函数中的一种方式,这种方式能让程序更加模块化,减少重复代码,并且提升代码的可测试性。在 FastAPI 中,依赖注入不仅可以简化 API 路由中的代码,还能提高整体代码结构的清晰度与可维护性。

1.1 依赖注入的基础概念

在 FastAPI 中,依赖注入是通过声明函数的参数来实现的。每当请求进入时,FastAPI 会自动地解析这些依赖并注入到处理函数中。依赖可以是数据库连接、外部 API 调用、共享资源(如缓存)等。依赖注入的主要好处是提升代码的复用性、可测试性,并且使得函数的职责更加明确。

python 复制代码
from fastapi import FastAPI, Depends

app = FastAPI()

# 创建一个依赖项
def get_query_param(q: str = None):
    return q

# 在路由中注入依赖项
@app.get("/items/")
async def read_item(query_param: str = Depends(get_query_param)):
    return {"query_param": query_param}

在上面的示例中,get_query_param 是一个简单的依赖项,它会获取请求中的查询参数 q。在 read_item 路由中,我们通过 Dependsget_query_param 依赖注入到 query_param 中。FastAPI 会自动调用 get_query_param,并将其返回值传递给 read_item

1.2 依赖的嵌套与复用

FastAPI 支持嵌套依赖注入,这意味着一个依赖项可以依赖于其他依赖项,形成嵌套依赖关系。例如,可以通过嵌套依赖项注入数据库连接、缓存系统、第三方 API 等共享资源,极大地提高了系统的可扩展性。

python 复制代码
from fastapi import Depends

# 创建一个数据库依赖项
def get_db_connection():
    return "Database Connection Established"

# 创建一个使用数据库的依赖项
def get_user_data(db: str = Depends(get_db_connection)):
    return {"user_id": 123, "db": db}

@app.get("/users/")
async def read_user(user_data: dict = Depends(get_user_data)):
    return user_data

这里,get_db_connection 负责提供数据库连接,get_user_data 依赖于 get_db_connection 来获取数据库连接。在 FastAPI 中,Depends(get_user_data) 会将 get_user_data 的返回值注入到 read_user 函数中。

1.3 依赖注入的高级特性

FastAPI 还支持更复杂的依赖注入场景,如:

  • 注入类实例: 可以通过依赖注入将类的实例注入到路由处理函数中,类似于传统的服务注入。
  • 生命周期管理: 通过 Depends 还可以管理依赖项的生命周期,例如,每个请求创建一个新的数据库连接实例。
  • 异步支持: 依赖项本身可以是异步的,这让 FastAPI 可以更高效地处理并发请求。
python 复制代码
class Database:
    def connect(self):
        return "Connected to DB"

    def close(self):
        return "Connection Closed"

# 注入类实例
def get_database():
    db = Database()
    db.connect()
    try:
        yield db
    finally:
        db.close()

@app.get("/data/")
async def get_data(db: Database = Depends(get_database)):
    return {"db_status": db.connect()}

在上面的例子中,get_database 返回一个数据库连接对象,在每个请求中创建并注入一个新的数据库实例。


2. ⚙️ 中间件概述与常见应用

FastAPI 的中间件系统使得开发者能够在请求和响应处理过程中添加额外的功能,例如日志记录、请求的时间统计、跨域资源共享(CORS)等。中间件是在请求生命周期中,路由处理函数之前或之后执行的处理组件。通过中间件,开发者可以在不改变业务逻辑的情况下进行全局处理。

2.1 中间件的基本概念

FastAPI 中的中间件是通过 Middleware 类来实现的,每个中间件类都需要实现一个异步方法来处理请求。在 FastAPI 中,中间件主要有两种类型:请求中间件和响应中间件。

  • 请求中间件: 在请求到达路由处理函数之前执行,用于修改请求数据。
  • 响应中间件: 在路由处理函数返回响应后执行,用于修改响应数据。
python 复制代码
from starlette.middleware.base import BaseHTTPMiddleware
from fastapi import FastAPI

class CustomMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        print(f"Request Path: {request.url.path}")
        response = await call_next(request)
        response.headers['X-Custom-Header'] = 'Value'
        return response

app = FastAPI()

# 将中间件添加到应用中
app.add_middleware(CustomMiddleware)

在上面的代码中,CustomMiddleware 是一个自定义的中间件,能够打印请求路径,并在响应中添加一个自定义的 header。

2.2 🛠️ CORS 中间件

跨源资源共享(CORS)是 Web 开发中常见的问题,尤其是在现代前端开发中,前后端分离的架构已经成为主流。在 FastAPI 中,可以通过 CORSMiddleware 来处理 CORS 问题,允许特定的前端应用访问后端接口。

python 复制代码
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# 设置允许跨域请求的来源
origins = [
    "http://localhost:3000",
    "https://myfrontend.com",
]

# 添加 CORS 中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],  # 允许所有 HTTP 方法
    allow_headers=["*"],  # 允许所有请求头
)

在这个例子中,CORSMiddleware 配置了哪些来源可以访问 API。通过设置 allow_origins,你可以指定允许访问的前端地址,保证 API 的安全性与正确性。

2.3 📝 请求日志中间件

请求日志是 Web 开发中不可或缺的部分,它帮助开发者追踪 API 请求的状态、响应时间以及错误信息。FastAPI 提供了中间件支持,使得请求日志的记录变得更加方便。通过使用中间件,可以在每次请求时自动记录请求和响应的相关信息。

python 复制代码
import logging
from starlette.middleware.base import BaseHTTPMiddleware
from fastapi import FastAPI

class LogRequestMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        logger = logging.getLogger("uvicorn")
        logger.info(f"Request: {request.method} {request.url.path}")
        response = await call_next(request)
        logger.info(f"Response: {response.status_code}")
        return response

app = FastAPI()

# 添加日志记录中间件
app.add_middleware(LogRequestMiddleware)

在这个例子中,LogRequestMiddleware 会记录每次请求的 HTTP 方法和请求路径,同时记录响应的状态码,帮助开发者进行请求的跟踪与调试。

2.4 ⏱️ 请求处理时间中间件

性能监控是 Web 开发中的另一项重要任务。通过中间件,开发者可以轻松地记录每个请求的处理时间。这对于优化 API 性能、提升响应速度非常重要。

python 复制代码
import time
from starlette.middleware.base import BaseHTTPMiddleware

class RequestTimingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        start_time = time.time()
        response = await call_next(request)
        end_time = time.time()
        processing_time = end_time - start_time
        response.headers["X-Processing-Time"] = str(processing_time)
        return response

app = FastAPI()

# 添加请求处理时间中间件
app.add_middleware(RequestTimingMiddleware)

在这个例子中,RequestTimingMiddleware 记录了每个请求的处理时间,并将其作为 X-Processing-Time header 添加到响应中,

开发者可以通过该信息来分析性能瓶颈。

2.5 ⚠️ 异常捕获中间件

FastAPI 还支持捕获和处理 API 中的异常。通过自定义中间件,开发者可以集中处理异常,将错误信息统一输出到日志中,或返回统一格式的错误响应。

python 复制代码
from starlette.middleware.base import BaseHTTPMiddleware
from fastapi import FastAPI
import logging

class ExceptionHandlingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        try:
            response = await call_next(request)
            return response
        except Exception as e:
            logging.error(f"Error occurred: {e}")
            return {"error": "Internal Server Error"}

app = FastAPI()

# 添加异常处理的中间件
app.add_middleware(ExceptionHandlingMiddleware)

在这个例子中,ExceptionHandlingMiddleware 会捕获所有异常并记录到日志中,同时返回一个统一的错误响应。


相关推荐
shiming887912 分钟前
python基于基于自然语言处理技术的话题文本分类
人工智能·python·自然语言处理·django
爱吃香菜---www12 分钟前
Scala隐式泛型
开发语言·后端·scala
我爱写代码?15 分钟前
Scala的隐式对象
开发语言·后端·scala
小参宿16 分钟前
【Stream流】
java·开发语言
编织幻境的妖17 分钟前
用户认证系统登录界面
前端·css·css3
tester Jeffky20 分钟前
探索HTML5与CSS3的Flex布局:构建现代网页设计的灵活框架
前端·css3·html5
Python当打之年22 分钟前
【55 Pandas+Pyecharts | 实习僧网Python岗位招聘数据分析可视化】
python·信息可视化·数据分析·pandas
灵性(๑>ڡ<)☆23 分钟前
智慧商城项目2(vue核心技术与实战)
前端·javascript·vue.js
爱跨境的笑笑25 分钟前
代理IP地址和端口是什么?怎么进行设置?
开发语言·php
Koikoi12335 分钟前
java引用相关(四大引用类型,软引用避免oom,弱引用表,虚引用和引用队列,可达性分析算法)
java·开发语言