术→技巧, 研发

FastAPI学习之项目结构

钱魏Way · · 92 次浏览

在设计 FastAPI 项目结构时,需要根据项目规模(小型/中型/大型)、项目类型(纯API/全栈应用/微服务)和团队协作需求灵活调整。

以下是针对不同场景的实践指南和示例:

核心设计原则

  • 模块化:按功能拆分代码(路由、模型、服务分离)。
  • 可扩展性:预留扩展点(如插件机制)。
  • 环境隔离:区分开发、测试、生产配置。
  • 文档友好:利用 FastAPI 的 OpenAPI 自动生成能力。

项目结构参考模板

小型项目(单一功能,1-2人开发)

my_project/
├── main.py          # 入口文件(路由、逻辑、配置集中管理)
├── requirements.txt
└── README.md

适用场景:快速原型、临时工具开发。

中型项目(模块化,团队协作)

my_app/
├── api/                 # 路由层
│   ├── endpoints/       # 按业务拆分路由
│   │   ├── users.py
│   │   └── items.py
│   └── routers.py       # 路由聚合
│
├── core/                # 核心配置
│   ├── config.py        # 环境变量管理
│   └── security.py      # 认证逻辑
│
├── models/              # 数据模型
│   ├── schemas.py       # Pydantic模型
│   └── database.py      # 数据库连接
│
├── services/            # 业务逻辑层
│   └── user_service.py
│
├── tests/               # 测试代码
│   ├── test_users.py
│   └── conftest.py      # pytest fixtures
│
├── static/              # 静态文件(可选)
├── templates/           # 模板引擎(可选)
│
├── main.py              # 应用入口
└── requirements.txt

适用场景:标准业务系统(如电商后台、CMS)。

大型项目(微服务架构)

project/
├── auth_service/        # 独立认证服务
│   └── (结构同中型项目)
│
├── order_service/       # 订单服务
│   └── (结构同中型项目)
│
├── payment_service/     # 支付服务
│   └── (结构同中型项目)
│
├── gateway/             # API网关
│   ├── routes/
│   └── middleware/      # 限流/认证中间件
│
└── shared/              # 公共依赖
    ├── common_models/   # 共享数据模型
    └── utils/           # 工具类库

适用场景:分布式系统、跨团队协作。

关键组件详解

路由设计(api/ 目录)

  • 按业务垂直拆分:每个功能模块独立文件(py,products.py)
  • 路由聚合示例
# api/routers.py
from fastapi import APIRouter
from .endpoints import users, items

router = APIRouter()
router.include_router(users.router, prefix="/users", tags=["users"])
router.include_router(items.router, prefix="/items", tags=["items"])

依赖管理(core/ 目录)

全局依赖注入

# core/dependencies.py
from fastapi import Depends

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# 在路由中使用
@router.get("/{user_id}")
async def read_user(user_id: int, db: Session = Depends(get_db)):
    return db.query(User).filter(User.id == user_id).first()

配置管理(core/config.py)

环境敏感配置分离

# core/config.py
from pydantic import BaseSettings

class Settings(BaseSettings):
    app_name: str = "My API"
    database_url: str = "sqlite:///./test.db"
    secret_key: str

    class Config:
        env_file = ".env"

settings = Settings()

不同项目类型的结构调整

纯API服务

重点组件

  • 强化schemas(数据校验)
  • 添加client_sdk/(生成调用SDK)
  • 完善docs/(API文档)

全栈应用(含前端页面)

新增目录

templates/           # Jinja2模板
static/
    ├── css/
    ├── js/
    └── images/

数据密集型服务

扩展结构

data/
    ├── migrations/   # 数据库迁移脚本
    └── analytics/    # 数据分析脚本

自动化与工具集成

项目脚手架(Cookiecutter模板)

pip install cookiecutter
cookiecutter https://github.com/tiangolo/full-stack-fastapi-postgresql

代码质量工具

# pyproject.toml
[tool.black]
line-length = 88

[tool.isort]
profile = "black"

[tool.mypy]
strict = true

CI/CD 配置

# .github/workflows/test.yml
name: Test
on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: |
          pip install -r requirements.txt
          pytest -v

演进式设计建议

  • 初始阶段:从简单结构开始,避免过度设计
  • 规模扩展时
    • 当单个文件超过 500 行时拆分模块
    • 出现重复代码时抽象公共组件
  • 团队协作时
    • 强制类型提示(mypy)
    • 统一路由命名规范(如全小写+下划线)

经典反模式

  • 面条式代码:所有逻辑堆砌在py
  • 循环依赖:models导入 services 同时 services 又导入 models
  • 配置硬编码:数据库密码直接写在代码中
  • 忽略测试目录:tests/未与业务代码同步更新

总结

  • 小型项目:保持简单,集中管理
  • 中型项目:严格分层,模块化拆分
  • 大型系统:服务拆分,共享公共库
  • 通用法则:高内聚低耦合,目录即文档

根据实际需求动态调整结构,始终以 可维护性团队效率 为核心目标。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注