FastAPI 入门系列 之 依赖注入!

这是我参与11月更文挑战的第29天,活动详情查看:2021最后一次更文挑战

FastAPI 有一个很大的亮点,那就是提供了一个简单易用,但是功能非常强大的依赖注入系统,使用依赖注入系统,我们可以轻而易举的把各种功能的组件集成到 FastAPI 应用中,接下来就一起来了解一下。

什么是依赖注入

所谓依赖注入,就是声明一些程序代码必须依赖的项,FastAPI 中称之为依赖项 dependencies,然后在实际运行中,FastAPI 会把所有的依赖项提供给有需要的程序,这个过程就是依赖注入。依赖注入非常适合在业务逻辑复用的场景使用,可以有效地减少代码重复,除此之外,在进行权限校验、身份验证、共享数据库连接等场景也非常适用。

使用依赖注入系统

简单使用

要是用依赖注入系统,首先需要创建依赖项,依赖项实际上是一个函数,如下:

async def verify_token(request: Request):
    token = request.headers.get("token")
    if not token:
        raise HTTPException(
            status_code=HTTP_401_UNAUTHORIZED,
            detail="token 不正确"
        )
    # 验证、解析token,假设解析出user_id···
    user_id = 111
    return user_id
复制代码

可见,声明依赖项和普通函数一样,可接收任意参数,返回任意信息。上面代码中,接收来自客户端的 request 对象并获取 header 中的 token,获取不到的话直接抛 HTTPException 异常(HTTPException 异常之后再介绍),会直接返回给客户端异常信息,获取到的话再对 token 进行验证、解析(例如JWT token 的解析),这里省略细节,假设解析出的 user_id 为111。

创建好依赖项之后,使用时在需要此依赖的路由函数的参数中使用Depends声明依赖,如下:

@app.get("/get_info")
async def get_info(user_id: int = Depends(verify_token)):
    # 通过user_id获取用户信息
    user_info = {
        "user_id": user_id,
        "name": "tigeriaf"
    }
    return user_info
复制代码

解释一下,上面的user_id: int = Depends(verify_token)对此接口声明了一个依赖Depends(verify_token),那么当该接口被调用的时候,先调用此依赖项函数,传递合适的参数,依赖函数执行,返回结果再传递给路由函数的参数,如 user_id。

请求示例:

image.png 验证失败的请求结果: image.png

可见,如果请求时不上送 token 信息,不会通过。

我们可以定义我们需要的任意依赖项,然后在需要的路由函数中声明使用。

把类当作被依赖对象

上面的依赖项是以函数的形式出现,其实 FastAPI 也支持以类的形式来创建依赖项。

class UserInfo:
    def __init__(self, request: Request):
        token = request.headers.get("token")
        if not token:
            raise HTTPException(
                status_code=HTTP_401_UNAUTHORIZED,
                detail="token 不正确"
            )
        # 验证、解析token,假设解析出user_id···
        self.user_id = 111
        self.name = "tigeriaf"


@app.get("/get_info")
async def get_info(user_info: UserInfo = Depends(UserInfo)):
    user_info = {
        "user_id": user_info.user_id,
        "name": user_info.name
    }
    return user_info
复制代码

上面的 UserInfo 是一个类,当接口被调用的时候,类对象就会被初始化,返回类的实例 user_info,然后在路由函数内获取对象的相关属性。

多层嵌套依赖项

FastAPI 支持多层嵌套依赖项,可以根据需求创建创建有子依赖项的依赖项,深度不受限制,使用方法也非常简单,只需在依赖函数内使用Depends声明依赖即可,此处不作详细展开。

总结

除此之外,FastAPI 还支持路由声明多个依赖、使用 yield 关键字的依赖项等,总之,FastAPI 依赖注入系统非常强大,值得学习。

原创不易,如果小伙伴们觉得有帮助,麻烦点个赞再走呗~

最后,感谢女朋友在工作和生活中的包容、理解与支持 !

猜你喜欢

转载自juejin.im/post/7036164175910944804