FastAPI 入门:一个后端开发者的实战笔记

刘芳~
2025-06-23 13:14
阅读 564

一、为什么选择 FastAPI?

一、为什么选择 FastAPI?

作为一名从事 Python 后端开发多年的开发者,我经历过 Django 的“全栈式重装部队”,也尝试过 Flask 的“轻装上阵”。但直到去年接手一个新项目时,我才真正接触到 FastAPI。它的出现让我眼前一亮:既快又现代化,还自带文档生成和异步支持,简直是为现代 Web 服务量身打造的工具。

我们团队当时负责一个中小型的 SaaS 后台系统,需要快速搭建一套 API 服务,用于支撑移动端和前端页面的数据交互。传统方案我们可能会选 Flask + SQLAlchemy 自己搭框架,或者直接上 Django REST Framework(DRF),但这次我们决定尝试一下社区中越来越火的 FastAPI。

接下来的内容,我会结合自己的亲身经历,分享我在使用 FastAPI 过程中的学习曲线、踩过的坑和最终收获。


二、项目背景与挑战

二、项目背景与挑战

我们的项目是一个在线教育平台的后台服务,主要功能包括:

  • 用户注册/登录
  • 视频课程管理(上传、分类)
  • 学习记录追踪
  • 评论与评分系统

面临的几个关键问题:

  1. 时间紧任务重,需要快速搭建原型并上线
  2. 团队成员对新框架接受度高,但需要有明确的学习路径
  3. 服务需支持并发请求,同时尽可能利用异步特性提升性能
  4. 接口设计要规范,后期便于接入前后端分离架构

传统的 Flask 框架虽然灵活,但在接口定义、参数校验和文档自动生成方面比较吃力,而 DRF 虽然成熟稳定,但配置复杂,启动慢,不利于快速迭代。于是我们把目光转向了 FastAPI。


三、技术选型与初步实践

三、技术选型与初步实践

FastAPI 基于 Starlette 实现,并内置了 Pydantic 进行数据模型验证,天然支持 Python 3.8+ 类型注解异步编程。这些特性让它在类型安全、代码可读性和性能层面都表现不俗。

我们采用的技术栈如下:

  • FastAPI:主框架
  • SQLModel:数据库建模(兼容 Pydantic,同时支持 SQLAlchemy)
  • PostgreSQL:数据库
  • Uvicorn:生产级 ASGI 服务器
  • JWT:用户认证机制
  • Docker:服务容器化部署

四、具体实现与核心代码示例

四、具体实现与核心代码示例

1. 快速创建一个项目结构

project/
├── app/
│   ├── __init__.py
│   ├── main.py
│   ├── models.py
│   ├── schemas.py
│   ├── database.py
│   └── routes/
│       └── user.py

2. 初始化 FastAPI 应用入口

app/main.py 中:

from fastapi import FastAPI
from app.routes import user

app = FastAPI(title="在线教育平台后台",
              description="FastAPI 新手入门实战项目",
              version="0.1")

app.include_router(user.router, prefix="/users", tags=["用户管理"])

3. 定义数据模型(Schema)

使用 Pydantic 来定义接口输入输出格式:

# schemas.py
from pydantic import BaseModel
from typing import Optional

class UserCreate(BaseModel):
    username: str
    email: str
    password: str

class UserResponse(BaseModel):
    id: int
    username: str
    email: Optional[str] = None

    class Config:
        orm_mode = True

4. 数据库模型

我们使用 SQLModel,可以无缝对接 SQLAlchemy 和 Pydantic:

# models.py
from sqlmodel import SQLModel, Field

class User(SQLModel, table=True):
    id: int = Field(default=None, primary_key=True)
    username: str
    email: str
    hashed_password: str

5. 数据库连接配置

# database.py
from sqlmodel import create_engine, Session

DATABASE_URL = "postgresql://user:password@localhost:5432/mydb"

engine = create_engine(DATABASE_URL)

def get_session():
    with Session(engine) as session:
        yield session

6. 定义路由与依赖注入

# routes/user.py
from fastapi import APIRouter, Depends, HTTPException
from app.schemas import UserCreate, UserResponse
from app.models import User
from app.database import get_session
from sqlmodel import select

router = APIRouter()

@router.post("/", response_model=UserResponse)
def create_user(user: UserCreate, session: Session = Depends(get_session)):
    db_user = User(**user.dict())
    session.add(db_user)
    session.commit()
    session.refresh(db_user)
    return db_user

@router.get("/{user_id}", response_model=UserResponse)
def read_user(user_id: int, session: Session = Depends(get_session)):
    user = session.get(User, user_id)
    if not user:
        raise HTTPException(status_code=404, detail="用户不存在")
    return user

五、踩坑经验分享

1. 异步函数返回值被包装成 awaitable 对象

我们在实现视频上传接口时,用了 async def upload_video(),但调用时忘了加 await,结果返回的是一个 coroutine 对象而不是响应内容。

✅ 解决方法:确保所有 async 函数调用都有 await,或在测试中启用 async 支持。

@app.post("/upload")
async def upload_video(file: UploadFile = File(...)):
    contents = await file.read()  # 记得 await
    return {"filename": file.filename}

2. SQLModel 的版本冲突导致无法运行

一开始我们用的是较老的 sqlmodel 版本,跟 Pydantic 冲突,初始化时报错。

✅ 解决方法:及时升级到最新版,注意与 FastAPI 及 Pydantic 的兼容性。

pip install --upgrade sqlmodel

3. 生产环境下的性能瓶颈初体验

本地用 uvicorn.run(app) 跑没问题,但上了测试服后高并发下性能下降明显。

✅ 优化方式:

  • 使用 Gunicorn 多 worker 启动
  • 启用 reload 功能(仅限开发环境)
  • 使用 --host 0.0.0.0 开放访问权限
gunicorn -w 4 -k uvicorn.workers.UvicornWorker app.main:app --bind 0.0.0.0:8000

4. 数据库连接池打满的问题

由于早期未使用连接池,高并发下频繁创建连接导致超时。

✅ 使用 SQLAlchemy 的 connection pool(通过 SQLModel 间接设置):

from sqlalchemy.pool import QueuePool

engine = create_engine(
    DATABASE_URL,
    poolclass=QueuePool,
    pool_size=10,
    max_overflow=20
)

六、实际效果与收益总结

经过两个月的开发和上线运行,我们团队收获颇丰:

方面 效果
开发效率 提升明显,接口定义清晰,减少了手动校验工作
文档质量 自动生成 Swagger UI + ReDoc,大大方便前后端协作
性能表现 平均响应时间 < 100ms,在千级 QPS 下仍保持稳定
维护成本 结构清晰,后续迭代难度低

尤其是在文档这块,再也不用自己写一遍再手动维护文档了,这对我们这样小团队来说非常友好。


七、给新手的几点建议

  1. 从简单例子开始,逐步了解 FastAPI 的核心概念,比如 Router、Depends、Pydantic 模型等;
  2. 多参考官方文档,很多高级用法(如中间件、WebSocket、Background Tasks)都有详细说明;
  3. 别怕犯错,踩坑是成长最快的途径,遇到错误记得查日志、看源码;
  4. 尽早引入测试,FastAPI 非常适合写单元测试和集成测试;
  5. 考虑异步场景,尤其涉及 I/O 密集操作(如文件上传、远程调用)时,尽量使用 async/await;
  6. 重视安全性,哪怕只是个练手项目,也要养成做鉴权的习惯(例如 JWT);

八、未来展望与发展趋势

随着 FastAPI 社区的不断壮大,越来越多的企业和开源项目开始采用它作为主力框架。相比 Flask 更现代、比 Django 更灵活,已经成为 Python 后端界的“新宠”。

再加上 TypeScriptSwagger/OpenAPI 的兴起,FastAPI 在构建可维护的现代化微服务架构中扮演着愈发重要的角色。

如果你正在考虑入门或重构后端服务,强烈推荐你试试 FastAPI —— 它真的会让你爱上写接口这件事。


结语

FastAPI 不只是另一个 Web 框架,更像是一种新的开发哲学。它将“类型即文档”、“异步优先”、“代码即文档”的理念贯彻到底,大大提升了开发效率和系统的可靠性。

希望这篇实战经验能为你打开 FastAPI 的世界之门。如果感兴趣,欢迎留言交流,我可以分享更多关于如何结合 JWT、OAuth2、Docker 等技术深入实战的经验。

Happy coding!🚀

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝