FastAPI 依赖注入之类依赖:使用类声明依赖项并简化查询参数
在 FastAPI 中,依赖注入(DI)不仅支持函数,还支持类作为依赖项,这使得代码更加模块化与易于维护。通过类依赖,开发者能够封装复杂的业务逻辑与参数验证,提高代码的可复用性与可读性。本文介绍了如何使用类来声明依赖项并应用于路径操作,展示了类依赖与函数依赖的差异以及如何使用 FastAPI 中的 Depends
来自动处理类实例的创建与注入,极大简化了查询参数的处理和验证过程。
文章目录
预备课:FastAPI 依赖注入之函数依赖:高效管理路径操作的全局共享资源
以下示例中使用的 Python 版本为 Python 3.10.15
,FastAPI 版本为 0.115.4
。
一 示例代码
from fastapi import Depends, FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
class CommonQueryParams:
def __init__(self, q: str | None = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip: commons.skip + commons.limit]
response.update({"items": items})
return response
依赖项通常被声明为函数,但也可以是其他可调用对象。Python 中的 可调用对象 是指任何可以像函数一样执行的对象。运行代码文件 di02.py 来启动应用:
$ uvicorn di02:app --reload
在 SwaggerUI 中可以查看在线文档:http://127.0.0.1:8000/docs
。
二 类依赖和函数依赖
# 定义一个类,用于封装查询参数
class CommonQueryParams:
def __init__(self, q: str | None = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
# 定义一个异步函数,作为依赖项返回查询参数字典
async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
"""
返回查询参数字典,用于处理请求中的查询参数。
参数与 CommonQueryParams 类中的一致。
"""
return {"q": q, "skip": skip, "limit": limit}
用于创建类实例的 __init__
方法,其参数与之前的 common_parameters
函数相同,FastAPI 会处理这些参数,包括数据转换、验证,并在 OpenAPI 文档中生成相应的 schema。
三 使用类声明依赖项
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip : commons.skip + commons.limit]
response.update({"items": items})
return response
FastAPI 调用 CommonQueryParams
类,创建该类的一个实例,并将其作为参数 commons
传递给路径操作函数。
四 类依赖的多种写法
1 第一种
FastAPI 通过 Depends(CommonQueryParams)
知道需要调用 CommonQueryParams
类,并从中提取参数以创建一个实例。此时,FastAPI 会执行数据转换、验证,并将创建的实例作为参数传递给函数。如图所示:
- 第一个
CommonQueryParams
仅为类型声明,对 FastAPI 并不产生特殊影响,它没有任何特殊的意义。 - 第二个
CommonQueryParams
与Depends
配合使用,才是 FastAPI 识别并处理依赖项的实际机制。
2 第二种
@app.get("/items02/")
async def read_items(commons=Depends(CommonQueryParams)):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip: commons.skip + commons.limit]
response.update({"items": items})
return response
声明类型是推荐的做法,因为这样编辑器就能识别 commons
参数的类型,进而提供代码补全、类型检查等帮助。
3 第三种
@app.get("/items02/")
async def read_items(commons: CommonQueryParams = Depends()):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip: commons.skip + commons.limit]
response.update({"items": items})
return response
如果这种写法难以理解,那么可以忽略它。
五 完整代码示例
from fastapi import Depends, FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
class CommonQueryParams:
def __init__(self, q: str | None = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip: commons.skip + commons.limit]
response.update({"items": items})
return response
@app.get("/items02/")
async def read_items(commons=Depends(CommonQueryParams)):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip: commons.skip + commons.limit]
response.update({"items": items})
return response
@app.get("/items02/")
async def read_items(commons: CommonQueryParams = Depends()):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip: commons.skip + commons.limit]
response.update({"items": items})
return response
六 源码地址
七 参考
[1] FastAPI 文档
标签:依赖,items,commons,查询,skip,FastAPI,limit,response,CommonQueryParams From: https://blog.csdn.net/u014394049/article/details/145121147