Fastapi接口路由【模块化、去耦合】

本文介绍了如何利用Fastapi的APIRouter将不同功能的API接口分别管理,降低系统耦合度。通过创建多个功能模块,每个模块包含业务逻辑和路由脚本,实现了模块的独立性和可复用性。在项目根目录下,通过服务启动脚本将各模块接口汇总并挂载到同一服务,方便调用。示例展示了目录结构和接口定义,展示了如何启动服务并调用接口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、前言

Fastapi 中有个 APIRouter 类,可以将从属不同功能api接口分离到多个文件中,降低系统耦合度。这样多个系统之间如果有重复的模块,就可以拖拖拽拽复制粘贴了。


二、实现

1.目录结构

project【项目根目录】
   |-----server_router【路由目录】
   |		|------keyword_auto【功能模块1|		|			|------utils【业务逻辑1|		|			|------server.py【路由脚本1|		|
   |		|------keyword_pick【功能模块2|		|			|------utils【业务逻辑2|		|			|------server.py【路由脚本2|		|
   |		|------semantic_search【功能模块3|					|------utils【业务逻辑3|					|------server.py【路由脚本3|		
   |-----server.py【服务启动脚本】

keyword_auto、keyword_pick、semantic_search 是部署在同一服务下的三个独立的功能模块,必要时可以拆开各自独立部署

2.文件内容

  1. 三个功能模块中的 server.py【各自定义自己的接口方法】
# 创建路由对象
from fastapi import APIRouter
app = APIRouter()


# 定义接口方法
@app.post("/custom")
async def root(data):
    return {"data": data, "code": 1, "msg": "请求成功"}



  1. 项目根目录下的 server.py【汇总各接口方法到同一服务下】
import uvicorn
from fastapi import FastAPI

# 引入路由
from server_router.keyword_auto.server import app as app_keyword_auto
from server_router.keyword_pick.server import app as app_keyword_pick
from server_router.semantic_search.server import app as app_semantic_search

# 创建服务
app = FastAPI()


# 路由挂载
app.include_router(app_keyword_auto, prefix='/keyword_auto', tags=['检索词联想', '列表页'])
app.include_router(app_semantic_search, prefix='/semantic_search', tags=['语义检索条件聚合', '列表页+详情页'])
app.include_router(app_keyword_pick, prefix='/keyword_pick', tags=['文本关键词提取', '建议生产环境下使用'])


if __name__ == '__main__':
	# 启动服务
    uvicorn.run(app="server:app", host='0.0.0.0', port=2333, workers=2)

调用方式:
ip:端口/挂载路由/模块各自路由
当前例子中的路由为 192.168.0.233:2333/keyword_auto/custom

### 实现 FastAPI 路由工厂模式下的自动注册 在 FastAPI 中,通过使用工厂模式可以更灵活地管理应用实例以及其依赖项。为了实现路由的自动注册功能,可以通过模块化设计和动态导入的方式完成。 #### 工厂模式的核心逻辑 在 `create_app` 函数中初始化 FastAPI 应用并加载路由模块。通常情况下,这涉及以下几个方面: - **FastAPI 对象创建**: 使用 `FastAPI()` 构造函数生成核心应用对象。 - **路由模块分离**: 将不同的 API 版本或业务逻辑拆分到独立的子模块中。 - **动态路由注册**: 配合 Python 的包机制,在运行时扫描指定目录中的路由文件,并将其挂载至主应用。 以下是基于引用内容[^1]的一个扩展方案: ```python from fastapi import FastAPI from pathlib import Path import importlib.util def load_routers_from_directory(directory_path: str, app: FastAPI): """ 动态加载指定目录下的所有路由模块 :param directory_path: 存放路由模块的目录路径 :param app: 主应用程序实例 """ base_dir = Path(__file__).parent / directory_path # 获取当前脚本所在目录下的目标文件夹 for file in base_dir.iterdir(): if file.is_file() and file.suffix == ".py" and not file.name.startswith("__"): module_name = f"{directory_path}.{file.stem}" # 组装模块名称 spec = importlib.util.spec_from_file_location(module_name, file.resolve()) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) # 假设每个模块都有一个名为 'router' 的变量存储路由对象 if hasattr(module, "router"): app.include_router( module.router, prefix=f"/{module.__name__.split('.')[-1]}", tags=[f"{module.__name__.split('.')[-1].capitalize()}"] ) def create_app(): app = FastAPI( title="CharmCode.cn", description="https://www.charmcode.cn", version="0.1.1", docs_url="/api/v1/docs", # 自定义文档地址 openapi_url="/api/v1/openapi.json" ) # 加载路由 load_routers_from_directory("routers", app) # routers 是存放路由模块的文件夹名 # 注册异常处理器和其他中间件... return app ``` #### 关键点解析 1. **动态加载模块** 利用 `pathlib` 和 `importlib` 提供的功能遍历指定目录内的 `.py` 文件,并逐一执行其中的内容。假设每个文件都导出了一个名为 `router` 的变量,则可以直接调用 `include_router` 方法绑定该路由。 2. **前缀与标签自动生成** 根据模块的名字为其分配唯一的 URL 前缀及 OpenAPI 文档中的分类标记 (tags),从而提升可读性和维护便利性[^1]。 3. **解耦设计原则** 此种方式不仅简化了初始配置过程,还遵循高内聚低耦合的设计理念——即让各个部分专注于自己的职责范围而不互相干扰。 #### 注意事项 尽管这种方法能够极大地减少重复劳动量,但也存在一些潜在风险需要注意: - 如果某些特定条件未满足(比如缺少必要的属性),可能会引发错误; - 当项目规模扩大后需谨慎评估性能开销是否合理; ---
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

什么都干的派森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值