Python Web 开发:FastAPI 依赖注入与中间件应用
目录
- 🧩 FastAPI 中的依赖注入
- ⚙️ 中间件概述与常见应用
- 🛠️ 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
路由中,我们通过 Depends
将 get_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
会捕获所有异常并记录到日志中,同时返回一个统一的错误响应。