fastapi之依赖注入(上)

225 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

依赖注入

依赖注入:fastapi提供了一个非常简单又使用的工具,他就是依赖注入。简单理解就是说:

  • 比如你定义了一个函数,这个函数中有一个特殊的形参。
  • 这个形参的值会有一个依赖关系,每当你调用这个函数时,会自动触发依赖关系,给这个特殊的形参赋值

依赖注入的用途:

  • 共享一块相同逻辑的代码块
  • 共享数据库连接
  • 权限认证,登录状态认证
  • 等等等

注入依赖简单的例子

  • 下面提供了一个非常加单的注入依赖的例子,使用它可以让多个路由具备三个通用的查询参数。
 from typing import Union
 ​
 from fastapi import Depends, FastAPI
 ​
 app = FastAPI()
 ​
 ​
 async def common_parameters(
     q: Union[str, None] = None, skip: int = 0, limit: int = 100
 ):
     return {"q": q, "skip": skip, "limit": limit}
 ​
 ​
 @app.get("/items/")
 async def read_items(commons: dict = Depends(common_parameters)):
     return commons
 ​
 ​
 @app.get("/users/")
 async def read_users(commons: dict = Depends(common_parameters)):
     return commons

使用依赖注入分两步:

  • 第一步:边写可以被依赖的对象,比如函数或者类,只要是可以变调用的对象都可以。
  • 第二步:在路径操作函数内,定义变量,给这个变量默认值,默认值使用Depends(可以来对象)

如此一来的好处就是:

  • 1,我们只需要定义一次三个通用查询查询的获取逻辑,却可以在任何需要的路由中方便的使用他们。
  • 2,另一个函数是通过可依赖对象的返回值,可以把需要的多个参数重新组装成新的数据。比如上例中,三个查询参数被我们封装到一个字典中,在给路由函数使用,是不是非常简洁呀。

被依赖的可以是类

  • 上面的例子中,通用查询参数定义在函数中,然后返回一个包含三个参数的字典
  • 除了函数之外,可依赖对象也可以是类,本质上说,只要是可以被调用的对象都可以当被依赖对象
 from typing import Union
 ​
 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: Union[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
  • 你看,我们定义了一个类:CommonQueryParams, 它可以做被依赖对象的要求是,它有__init__函数,这个初始化函数内定义了三个通用查询参数,有了这个之后,就可以接收三个参数了。
  • 然后在编写路径操作函数时,common参数的类型就不是字典了,而是CommonQueryParams,Depends内使用的是CommonQueryParams
  • 这样一来我们可以使用类实行的依赖对象,也可以使用函数形式的依赖对象。
  • 不论是何种形式的依赖对象,我们定义的被依赖参数可以使用类型转换、类型校验、openapi等功能。

类依赖注入简化形式

  • 上面我们使用类形式的依赖注入,看起来优点冗余对吧:commons: CommonQueryParams = Depends(CommonQueryParams)
  • 对于这种形式,有一个简写方式:commons: CommonQueryParams = Depends(),此时fastapi知道Depends括号内依赖的是什么。


\