基于 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中添加应用专属中间件依赖注入:在子应用级别管理依赖(如用户权限校验)
这种结构适合中大型项目,保持各应用高内聚低耦合,同时复用公共资源。




