基于 FastAPI 多应用模块化 的最佳实践实现
以下是基于 FastAPI 多应用模块化 的最佳实践实现,包含子应用路由、静态文件、模板渲染等功能,并保持项目结构清晰:
项目结构
project/ ├── apps/ # 子应用目录 │ ├── app1/ # 子应用1 │ │ ├── __init__.py │ │ ├── routes.py # 子应用路由 │ │ ├── static/ # 子应用静态文件(CSS/JS) │ │ └── templates/ # 子应用Jinja2模板 │ ├── app2/ # 子应用2(结构同app1) │ └── ... ├── core/ # 核心配置 │ ├── config.py # 全局配置 │ └── templates/ # 全局模板(可选) ├── static/ # 全局静态文件 ├── main.py # 主入口文件 └── requirements.txt
1. 主入口文件 (main.py
)
from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware import os app = FastAPI(title="Multi-App Project") # 加载子应用 def register_sub_apps(): apps_dir = "apps" for app_name in os.listdir(apps_dir): if os.path.isdir(f"{apps_dir}/{app_name}"): # 动态导入子应用路由 module = __import__(f"apps.{app_name}.routes", fromlist=["router"]) # 挂载到主APP,URL前缀为/apps/{app_name} app.mount(f"/apps/{app_name}", module.router) register_sub_apps() # 全局静态文件 app.mount("/static", StaticFiles(directory="static"), name="global_static") # CORS设置(可选) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], )
2. 子应用示例 (apps/app1/routes.py
)
from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates import os router = APIRouter(prefix="", tags=["app1"]) # 子应用静态文件(访问URL: /apps/app1/static/*) router.mount( "/static", StaticFiles(directory=os.path.join(os.path.dirname(__file__), "static")), name="app1_static" ) # 子应用模板(优先查找子应用模板,不存在时回退到全局模板) templates = Jinja2Templates(directory=[ os.path.join(os.path.dirname(__file__), "templates"), "core/templates" # 全局模板回退路径 ]) @router.get("/", response_class=HTMLResponse) async def app1_home(request: Request): return templates.TemplateResponse( "app1/index.html", # 模板路径 {"request": request, "title": "App1 Home"} ) @router.get("/api/data") async def get_data(): return {"app": "app1", "data": [1, 2, 3]}
3. 模板示例 (apps/app1/templates/app1/index.html
)
<!DOCTYPE html> <html> <head> <!-- 引用子应用静态文件 --> <link href="/apps/app1/static/app1.css" rel="stylesheet"> <title>{{ title }}</title> </head> <body> <h1>Welcome to {{ title }}!</h1> <!-- 引用全局静态文件 --> <img src="/static/global-logo.png"> <script src="/apps/app1/static/app1.js"></script> </body> </html>
4. 全局配置 (core/config.py
)
from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent class Settings: PROJECT_NAME = "Multi-App Project" TEMPLATE_DIRS = [ BASE_DIR / "core/templates", # 全局模板 ] settings = Settings()
5. 运行与测试
安装依赖:
pip install fastapi uvicorn jinja2 python-multipart
启动服务:
uvicorn main:app --reload
访问测试:
子应用主页:
http://127.0.0.1:8000/apps/app1/
子应用API:
http://127.0.0.1:8000/apps/app1/api/data
全局静态文件:
http://127.0.0.1:8000/static/global-logo.png
关键设计原则
模块化路由:每个子应用通过
APIRouter
独立管理路由,主应用动态挂载。静态文件隔离:子应用静态文件通过
/apps/{app_name}/static/
隔离,避免命名冲突。模板继承机制:优先使用子应用模板,未找到时回退到全局模板。
生产环境优化:
使用
Nginx
代理静态文件提升性能模板预编译(如
jinja2.Environment(auto_reload=False)
)
扩展建议
数据库:为每个子应用创建独立的
models.py
和database.py
中间件:在子应用
routes.py
中添加应用专属中间件依赖注入:在子应用级别管理依赖(如用户权限校验)
这种结构适合中大型项目,保持各应用高内聚低耦合,同时复用公共资源。