FastAPI中如何减少多路由重复校验ID路径参数的样板代码
路由重复存在性校验精简方案
这是FastAPI + SQLAlchemy技术栈下非常常见的样板代码场景,不需要为每个模型单独编写依赖函数,用依赖工厂就可以实现一套逻辑适配所有模型的校验需求,也是目前这类场景的通用标准实践。
通用依赖工厂实现
核心思路是写一个可配置的工厂函数,传入对应CRUD查询方法、404提示信息,返回包装好的依赖项,所有校验逻辑只需要写一次:
from fastapi import Depends, HTTPException, status from sqlalchemy.orm import Session # 导入你项目里已有的数据库会话依赖 from app.dependencies import get_db def get_exist_record(query_func, not_found_detail: str): def _dependency(id: int, db: Session = Depends(get_db)): record = query_func(db=db, id=id) if not record: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=not_found_detail ) return record return _dependency
路由使用示例
针对你写的council相关三个路由,只需要在路由参数里声明依赖,就能直接拿到已经校验存在的council对象,接口内部完全不需要再写重复的查询、判空、抛错逻辑:
from app import crud # 定义GET接口 @router.get("/councils/{id}") def fetch_council( council = Depends(get_exist_record(crud.council.get_by_id, "Council not found")) ): # 这里拿到的council一定是数据库存在的记录,直接使用即可 return council # 定义PUT接口 @router.put("/councils/{id}") def modify_council( council = Depends(get_exist_record(crud.council.get_by_id, "Council not found")), payload: CouncilUpdateSchema = ... ): # 直接基于已查询到的council做更新操作即可 pass # 定义DELETE接口 @router.delete("/councils/{id}") def remove_council( council = Depends(get_exist_record(crud.council.get_by_id, "Council not found")) ): # 直接执行删除逻辑即可 pass
后续处理其他模型(比如用户、帖子)的同类型校验时,只需要传入对应模型的get_by_id方法和匹配的404提示,不需要再重复写判空抛错的代码。
可选优化
如果你项目里所有CRUD类都统一实现了get_by_id方法,还可以把工厂的入参简化为CRUD实例,进一步减少重复代码:
def get_exist_record(crud_instance, not_found_detail: str): def _dependency(id: int, db: Session = Depends(get_db)): record = crud_instance.get_by_id(db=db, id=id) if not record: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=not_found_detail ) return record return _dependency # 可以提前把各模型的依赖定义好,路由里直接引用 council_exist_dep = Depends(get_exist_record(crud.council, "Council not found")) user_exist_dep = Depends(get_exist_record(crud.user, "User not found"))
如果部分模型的主键不是int类型、或者路径参数名不是id,只需要给工厂函数增加对应的配置项即可,核心校验逻辑完全不需要改动。
这种实现完全契合FastAPI的依赖注入设计,不会额外增加性能开销,还能自动在OpenAPI文档里生成对应的404响应说明,灵活度远高于硬编码的中间件或者装饰器方案。
内容的提问来源于stack exchange,提问作者Shiladitya Bose
相关产品推荐
相关产品推荐

