技术文章FastAPI 解读 by Gascognya

FastAPI 依赖注入详解:概念

2020-10-24  本文已影响0人  Gascognya

FastAPI得力于TypingPydantic以及Inspect,强大的类型库和反射库,给与了其进行类型检测和依赖注入的能力。

为什么可以进行类型检测

endpoint 指的是我们所编写的,处理request请求的函数。而我们会将希望从HTTP报文中获取的参数,填写在endpoint参数的位置。
Inspect库是Python强大的反射库,它可以实现自省,对函数的参数进行检测,得到它们的信息。包括参数名,标注的类型,默认值,允许的传值方式。

def test(a: int, b: str = "b_str"):
    pass

sig = inspect.signature(test)
params = dict(sig.parameters)
参数字典

我们可以看到,每个参数会被解析为一个Parameter对象,里面记录了参数的各种信息。
annotationdefault代表着类型注解和默认值,kind表示允许何种方式传参。
empty是用来做判断的工具,我们可以看到当annotationdefault未标注时,其类型是<class 'inspect._empty'>,当我们想判断是否有标注时,就需要与其做比较,为了方便,empty用来代表<class 'inspect._empty'>。只需要与他进行判断即可。

这样,一个函数的参数信息便是已知的,进而,一个endpoint所需要的参数信息也是已知的。框架知道我们的endpoint需要什么样的参数。

为什么需要类型检测

FastAPI高度集成OpenAPI(即SwaggerUI),参数类型检测,可以生成信息更加明确和丰富的API文档。这对于效率上来说是飞跃性的提升。后端只需要把endpoint写出来,框架就会将信息丰富的API文档自动生成出来。
另一方面,就是为依赖注入提供了基础。

为什么需要依赖注入

如果你了解spring的话,你一定知道spring的核心技术是IOCAOPIOCDI的前提,DIIOC的一种实现。

FastAPI的依赖注入,主要是为了解决两个问题。

  1. 在endpoint之前执行一些逻辑,这更加符合依赖的字面意思,本件事(endpoint)必须依赖于某些事(依赖项)的成功执行。并获取他们的返回值
  2. 智能的依赖项填充,我们接收的request可能包含大量字段,我们也可能需要他们作为参数,生成各种对象。例如我的request中包含name, age, email, token, count, title, article我需要让他们满足
    (User(name, age, email), Depend(verify_token), count, Article(title, article))等一系列参数,正常情况下我们只能自己手动实例化或调用这些内容。但是依赖注入帮我们将这些步骤都完成了,这得利于inspect的反射,可以检测每个角色都需要什么样的参数。

从广义上来讲,endpoint执行前所需要准备的所有项,都属于依赖系统的范畴。FastAPI的依赖系统,负责为endpoint准备“环境”。

那么,这些项都是指的哪些?

重点在于Depnds()

Depends()可以携带一个函数,或者一个类。返回的结果是其result,或者实例。
所有依赖项都可以有自己的参数,这些参数是从报文中拦截。

这就像派发快递的小哥,而依赖项是走在你前面的人。快递小哥会优先将他需要的快递派发给他,在剩余的快递中寻找你所需的。如果有差错,那就说明出了大问题,你们之间的所需起了冲突

  1. Depends()有两个参数,dependencyuse_cache,前者是我们的依赖项,而后者,代表的是是否使用缓存。
    缓存的意义在于,假设在解决依赖的过程中,有一个依赖项不止执行一次,他可能被多次需求。但我们不希望多次执行它。我们便可以使用缓存来解决。
    缓存默认置为True,我们不需要手动开启它,但是某些情况下,我们希望同一个依赖项多次执行,那么便可以手动置为False
  2. 依赖项可以写在装饰器的dependencies参数中,例如:
    @app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)])
    这代表着我们不需要这个依赖项的结果,只需要其顺利执行。
  3. 依赖项中可以使用 yieldcontext,例如获取数据库session的依赖项,我们可能只需要其不断产生session,而不是将整个函数重新执行一次,便可以用yield不断为所有需求方提供yield。而context可以帮我们更好的管理生成的依赖项

参考官方文档:https://fastapi.tiangolo.com/zh/tutorial/dependencies/dependencies-with-yield/

上一篇下一篇

猜你喜欢

热点阅读