前端 + FastAPI 项目完整目录结构

我给你一套生产级、可直接落地的「前端 + FastAPI 全栈项目完整目录结构」,兼顾「工程化规范、易维护性、前端开发习惯」,你可以直接按这个结构建项目,后续对接 AI 流式接口、部署上线都不用改结构。

一、项目总目录(前端+后端一体化)

fullstack-ai-project/  # 项目根目录
├── frontend/          # Vue3 前端项目(基于Vite)
├── backend/           # FastAPI 后端项目
├── docker-compose.yml # 一键启动配置(前端+后端+数据库)
├── .gitignore         # 全局忽略文件
└── README.md          # 项目说明(部署/启动步骤)

二、后端(FastAPI)目录结构(重点)

贴合 Python 工程化规范,同时适配前端「模块化」思维:

backend/
├── app/                # 核心应用代码(前端理解:src目录)
│   ├── __init__.py     # 包初始化文件(空文件即可)
│   ├── main.py         # FastAPI 入口文件(启动、跨域、路由注册)
│   ├── api/            # 接口路由(前端理解:router目录)
│   │   ├── __init__.py
│   │   ├── v1/         # 接口版本管理(推荐v1,方便后续迭代)
│   │   │   ├── __init__.py
│   │   │   ├── auth.py # 登录/鉴权接口
│   │   │   ├── user.py # 用户管理接口
│   │   │   ├── upload.py # 文件上传接口
│   │   │   └── ai.py   # AI 流式接口
│   ├── core/           # 核心配置(前端理解:config目录)
│   │   │   ├── __init__.py
│   │   │   ├── config.py # 全局配置(数据库、JWT、AI API Key)
│   │   │   └── dependencies.py # 依赖注入(数据库会话、鉴权)
│   ├── models/         # 数据库模型(前端理解:schema/model)
│   │   │   ├── __init__.py
│   │   │   └── user.py # 用户表模型
│   ├── schemas/        # 数据校验模型(前端理解:TS接口)
│   │   │   ├── __init__.py
│   │   │   ├── user.py # 用户相关请求/响应模型
│   │   │   └── ai.py   # AI 接口请求/响应模型
│   ├── crud/           # 数据库操作(前端理解:api/request)
│   │   │   ├── __init__.py
│   │   │   └── user.py # 用户CURD
│   ├── utils/          # 工具函数(前端理解:utils)
│   │   │   ├── __init__.py
│   │   │   ├── jwt.py  # JWT 工具
│   │   │   ├── password.py # 密码加密
│   │   │   └── ai.py   # AI API 调用工具
│   └── static/         # 静态文件(上传的图片/文件)
│       └── uploads/
├── .dockerignore       # Docker 忽略文件
├── .env                # 环境变量(本地开发,不上传git)
├── .env.example        # 环境变量示例(上传git,标注必填项)
├── Dockerfile          # 后端Dockerfile
├── requirements.txt    # 依赖清单
└── uvicorn_config.py   # uvicorn 启动配置(可选)

关键文件示例(保证可运行)

  1. backend/app/core/config.py(全局配置,从环境变量读取)
from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    # 数据库配置
    DATABASE_URL: str = "mysql+pymysql://root:123456@mysql:3306/fastapi_demo"
    # JWT配置
    SECRET_KEY: str = "your-secret-key-123456"
    ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
    # AI API配置
    DOUBAO_API_KEY: str = ""
    # 跨域配置
    CORS_ORIGINS: list = ["*"]

    # 加载.env文件
    model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")

# 全局配置实例
settings = Settings()
  1. backend/app/main.py(入口文件,注册路由)
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from app.api.v1 import auth, user, upload, ai
from app.core.config import settings

# 初始化FastAPI
app = FastAPI(
    title="前端+FastAPI全栈项目",
    description="包含用户管理、文件上传、AI流式接口",
    version="1.0.0"
)

# 跨域配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.CORS_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由(前端理解:app.use('/api/v1', router))
app.include_router(auth.router, prefix="/api/v1/auth", tags=["认证"])
app.include_router(user.router, prefix="/api/v1/user", tags=["用户"])
app.include_router(upload.router, prefix="/api/v1/upload", tags=["文件上传"])
app.include_router(ai.router, prefix="/api/v1/ai", tags=["AI接口"])

# 静态文件服务(上传文件访问)
app.mount("/static", StaticFiles(directory="app/static"), name="static")

# 根路由
@app.get("/")
def root():
    return {"message": "后端服务已启动,访问 /docs 查看接口文档"}
  1. backend/app/api/v1/auth.py(路由示例,拆分模块化)
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.core.dependencies import get_db
from app.schemas.user import UserLogin
from app.crud.user import get_user_by_username
from app.utils.jwt import create_access_token
from app.utils.password import verify_password

router = APIRouter()

@router.post("/login")
def login(user: UserLogin, db: Session = Depends(get_db)):
    # 查用户
    db_user = get_user_by_username(db, username=user.username)
    if not db_user:
        return {"code": 401, "msg": "用户名不存在", "data": None}
    # 验证密码
    if not verify_password(user.password, db_user.password):
        return {"code": 401, "msg": "密码错误", "data": None}
    # 生成Token
    access_token = create_access_token(data={"sub": db_user.username})
    return {"code": 200, "msg": "登录成功", "data": {"token": access_token}}

三、前端(Vue3)目录结构(Vite+Pinia+Axios)

贴合前端工程化规范,适配全栈联调场景:

frontend/
├── public/             # 静态资源(不打包)
├── src/
│   ├── api/            # 接口请求(和后端路由对应)
│   │   ├── index.js    # Axios 封装
│   │   ├── auth.js     # 认证相关接口
│   │   ├── user.js     # 用户相关接口
│   │   ├── upload.js   # 文件上传接口
│   │   └── ai.js       # AI 流式接口
│   ├── assets/         # 静态资源(图片/样式)
│   ├── components/     # 通用组件
│   │   ├── common/     # 公共组件(按钮/输入框)
│   │   ├── auth/       # 认证组件(登录/注册)
│   │   └── ai/         # AI 聊天组件
│   ├── layouts/        # 布局组件
│   ├── pages/          # 页面组件
│   │   ├── Login.vue   # 登录页
│   │   ├── User.vue    # 用户管理页
│   │   ├── Upload.vue  # 文件上传页
│   │   └── AIChat.vue  # AI 聊天页
│   ├── pinia/          # 状态管理
│   │   ├── index.js
│   │   └── userStore.js # 用户状态
│   ├── router/         # 路由
│   │   └── index.js
│   ├── utils/          # 工具函数
│   │   ├── request.js  # Axios 拦截器(Token、统一响应)
│   │   └── sse.js      # SSE 流式处理工具
│   ├── App.vue
│   └── main.js
├── .dockerignore       # Docker 忽略文件
├── .env.development    # 开发环境变量
├── .env.production     # 生产环境变量
├── Dockerfile          # 前端Dockerfile
├── index.html
├── package.json
└── vite.config.js      # Vite 配置(代理、端口)

关键文件示例

  1. frontend/src/utils/request.js(Axios 封装,对接后端统一响应)
import axios from 'axios'
import { useUserStore } from '@/pinia/userStore'

// 创建Axios实例
const service = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api/v1',
  timeout: 10000
})

// 请求拦截器(添加Token)
service.interceptors.request.use(
  (config) => {
    const userStore = useUserStore()
    if (userStore.token) {
      config.headers.Authorization = `Bearer ${userStore.token}`
    }
    return config
  },
  (error) => Promise.reject(error)
)

// 响应拦截器(统一处理响应)
service.interceptors.response.use(
  (response) => {
    const res = response.data
    // 统一处理code
    if (res.code !== 200) {
      // 登录失效
      if (res.code === 401) {
        const userStore = useUserStore()
        userStore.logout()
        window.location.href = '/login'
      }
      // 提示错误
      ElMessage.error(res.msg || '请求失败')
      return Promise.reject(res)
    }
    return res
  },
  (error) => {
    ElMessage.error(error.message || '网络错误')
    return Promise.reject(error)
  }
)

export default service
  1. frontend/vite.config.js(配置代理,解决开发跨域)
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  server: {
    port: 8080,
    proxy: {
      // 代理后端接口,避免开发跨域
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true
      }
    }
  }
})

四、全局配置文件

  1. docker-compose.yml(项目根目录,一键启动)
version: '3.8'

services:
  # 前端服务
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "8080:80"
    depends_on:
      - backend
    restart: always
    networks:
      - fullstack-network

  # 后端服务
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    depends_on:
      - mysql
    environment:
      - DATABASE_URL=mysql+pymysql://root:123456@mysql:3306/fastapi_demo
      - SECRET_KEY=your-secret-key-123456
      - CORS_ORIGINS=["*"]
    restart: always
    networks:
      - fullstack-network

  # 数据库服务
  mysql:
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=fastapi_demo
    volumes:
      - mysql-data:/var/lib/mysql
    restart: always
    networks:
      - fullstack-network

# 网络配置
networks:
  fullstack-network:
    driver: bridge

# 数据卷(持久化数据库)
volumes:
  mysql-data:
  1. .gitignore(全局忽略)
# 后端
backend/__pycache__/
backend/.env
backend/app/static/uploads/
backend/venv/

# 前端
frontend/node_modules/
frontend/dist/
frontend/.env
frontend/.vscode/
frontend/package-lock.json

# Docker
*.dockerignore
.docker-compose.override.yml

# 通用
.DS_Store
*.log
.vscode/
.idea/

五、核心优势(适配前端开发习惯)

  1. 模块化拆分:后端按「接口/配置/模型/工具」拆分,和前端「api/config/components/utils」一一对应,易理解、易维护;
  2. 环境隔离:前端/后端都有 .env 环境变量,开发/生产环境配置分离;
  3. Docker 友好:每个模块都有独立的 Dockerfile,docker-compose 一键启动所有服务;
  4. 可扩展性:新增 AI 功能只需在 backend/app/api/v1/ai.pyfrontend/src/api/ai.js 中添加代码,不改动核心结构;
  5. 工程化规范:符合 Python/FastAPI 官方规范 + 前端 Vue 生态规范,面试时展示这个结构会加分。

总结

  1. 目录核心逻辑:「前端/后端」目录分离,内部按「功能模块」拆分,前后端路由一一对应,降低联调成本;
  2. 落地性:直接按这个结构建文件夹,把之前写的 FastAPI 接口、Vue3 组件、AI 流式代码填充进去即可;
  3. 扩展性:后续加 Redis、RAG 知识库、CI/CD 都能在这个结构上扩展,不用重构。

如果需要我补充某个具体文件的完整代码(比如 backend/app/crud/user.pyfrontend/src/api/ai.js),或者提供「项目初始化脚本」,直接说就行。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容