FastAPI 依赖注入详解:概念

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准备“环境”。

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

  • 普通参数
  • 参数校验 Path(),Query()
  • 额外参数 Header(),Cookie(),Body(),Form(),File()
  • 依赖项 Depends(),Security()

重点在于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/

下一篇 FastAPI 依赖注入详解: 处理依赖树 https://www.jianshu.com/p/9685f6b7ca24

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341