在fastapi项目开发中,依赖注入机制可以帮助我们管理可复用的逻辑单元,而根据请求头动态切换依赖,能够让我们在不修改接口核心逻辑的前提下,适配不同的请求场景,比如区分不同版本的客户端、不同权限等级的用户等。

基础依赖定义
首先我们需要定义多个不同的依赖实现,这些依赖会实现相同的接口或者功能,后续根据请求头的内容选择返回对应的依赖实例。以下示例定义了两个处理用户信息的依赖类,分别用于普通用户和管理员用户的信息解析。
from fastapi import Depends, FastAPI, Request
# 普通用户依赖类
class NormalUserDependency:
def __init__(self, request: Request):
self.request = request
def get_user_info(self):
# 普通用户的信息解析逻辑
return {"user_type": "normal", "source": "normal_dependency"}
# 管理员用户依赖类
class AdminUserDependency:
def __init__(self, request: Request):
self.request = request
def get_user_info(self):
# 管理员用户的信息解析逻辑
return {"user_type": "admin", "source": "admin_dependency"}
app = FastAPI()
动态依赖切换逻辑实现
接下来我们需要创建一个工厂函数,这个函数会作为fastapi的依赖项,在函数内部解析请求头,根据请求头的内容返回对应的依赖实例。这里我们使用Request对象来获取请求头信息。
# 动态依赖工厂函数
def dynamic_user_dependency(request: Request):
# 获取请求头中的user-type字段,默认值为normal
user_type = request.headers.get("user-type", "normal")
if user_type == "admin":
return AdminUserDependency(request)
else:
return NormalUserDependency(request)
接口中使用动态依赖
定义好动态依赖之后,我们就可以在接口的路径操作函数中依赖注入这个动态依赖,从而根据请求头自动切换依赖实现。
@app.get("/user/info")
def get_user_info(user_dependency=Depends(dynamic_user_dependency)):
return user_dependency.get_user_info()
当我们发送请求时,如果请求头中user-type为admin,接口会返回管理员依赖的信息;如果没有该请求头或者值为其他内容,会返回普通用户依赖的信息。
复杂场景扩展
如果需要根据多个请求头字段组合判断,或者依赖需要更复杂的初始化逻辑,也可以在工厂函数中扩展判断逻辑。比如同时根据client-version和user-role两个请求头切换依赖:
def complex_dynamic_dependency(request: Request):
client_version = request.headers.get("client-version", "1.0")
user_role = request.headers.get("user-role", "guest")
# 根据版本和角色组合返回不同依赖
if client_version == "2.0" and user_role == "vip":
return AdminUserDependency(request)
else:
return NormalUserDependency(request)
注意事项
- 请求头的字段名获取时需要注意大小写,fastapi中获取的请求头字段名是小写的,即使请求中发送的是大写字段名,也会被转换为小写。
- 如果依赖需要异步初始化,工厂函数可以定义为异步函数,返回的依赖实例也可以支持异步方法。
- 动态依赖的工厂函数本身也可以作为其他依赖的依赖,实现多层级的动态切换逻辑。
动态依赖切换的核心思路是通过一个中间工厂函数作为依赖入口,在函数内部根据请求上下文(这里是请求头)选择具体的依赖实现,再返回给路径操作函数使用,这样既保留了依赖注入的优势,又实现了灵活的动态适配。