FastAPI 入门:Python 后端开发新手指南

马浩宇
2025-06-30 03:04
阅读 536

引言:我是怎么开始用 FastAPI 的?

引言:我是怎么开始用 FastAPI 的?

我是一个干了五年后端的 Python 工程师,经历过从 Flask、Django 到现在的 FastAPI。坦白讲,刚接触 FastAPI 的时候,我还挺抵触的。心想:“这玩意儿看起来不就是个新瓶装旧酒的小轮子吗?”结果一次项目实战让我彻底改变了看法。

事情是这样的,那会我们团队要启动一个新的内部服务,需要支持高并发、快速上线、接口文档自动化这些需求。一开始我们还想用熟悉的 Django + DRF(Django REST Framework),但是因为性能瓶颈的问题,加上文档生成这块还是需要额外配置,最后决定试试看社区讨论很多的 FastAPI。

这一试不要紧,一发不可收拾。FastAPI 确实让我感受到了什么叫“现代”、“高效”,并且它天生就适合做 API 服务。

所以今天我想结合自己真实的项目经历,来写一篇给新手的《FastAPI 入门指南》,希望对刚入坑 Python 后端的你有所帮助。


我们当时遇到的问题

我们当时遇到的问题

我们的项目是一个内部的用户行为采集系统。简单点说,就是前端每次触发一个事件(比如点击、浏览页面等),都需要通过 HTTP 请求发送到后端,进行数据入库和处理。项目要求如下:

  • 高并发请求支持
  • 接口文档自动生成,方便前后端协作
  • 数据校验严格,避免脏数据
  • 性能不能太差,最好接近 Go、Node.js 这类语言水平(当然不能完全比,但至少不要太慢)

为什么 Django 不够用了?

Django 是个很成熟、功能齐全的框架,但是在这种以轻量级 API 为主的场景下:

  1. 初始化较重:尤其是 ORM 和中间件加载,启动时间长;
  2. 异步支持不够原生:虽然 Django 支持 async,但还不是第一优先级;
  3. 文档生成需要手动维护或引入 Swagger 扩展
  4. 性能问题:在面对几万 QPS 场景时容易成为瓶颈;

所以我们尝试了 FastAPI,结果发现它的特点正好解决了我们的问题。


为什么选择 FastAPI?

先说结论:FastAPI 是基于 Starlette 的高性能 Web 框架,并且内置了 OpenAPI 文档(Swagger UI / ReDoc)。它最大的几个优势包括:

  • 速度快:接近 Node.js 的性能;
  • 异步友好:原生支持 async/await;
  • 自动生成 API 文档:基于 Pydantic 模型自动生成请求体格式和接口文档;
  • 类型检查与自动注解:利用 Python 的类型提示来做参数校验;
  • 插件生态丰富:配合 JWT、SQLAlchemy、Tortoise ORM、Redis 等都能很好地工作;
  • 适合构建微服务架构:轻量化 + 高性能 + 可拆分性强;

实践方案:FastAPI + SQLAlchemy + PostgreSQL + Uvicorn

这里我详细分享一下我们最终的架构方案:

User Event Client → [FastAPI] → [SQLAlchemy ORM] → [PostgreSQL]
                             ↘ [Redis 缓存]
                             ↘ [Kafka 异步写队列]

这套架构我们运行了两年多,基本稳定可靠。接下来我会重点讲一下我们在搭建过程中的一些关键实践。


快速上手:Hello World 开始你的 FastAPI 应用

首先,安装 FastAPI 和 Uvicorn:

pip install fastapi uvicorn

创建一个 main.py 文件:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "欢迎来到我的第一个 FastAPI 服务!"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

然后运行:

python main.py

访问 http://localhost:8000/docs 就能看到自动生成的 Swagger 文档界面!


项目结构与代码组织建议

刚开始学的时候,很多人喜欢把所有逻辑都塞进 main.py,这样很快就会失控。我在项目初期也犯过这个错误,后来整理了一套比较通用的目录结构:

myproject/
├── app/
│   ├── __init__.py
│   ├── main.py           # 启动文件
│   ├── api/              # 接口路由层
│   │   ├── __init__.py
│   │   └── user.py
│   ├── models/           # 数据库模型层
│   │   ├── __init__.py
│   │   └── user_model.py
│   ├── schemas/          # Pydantic Model,用于数据验证
│   │   ├── __init__.py
│   │   └── user_schema.py
│   └── database.py       # 数据库连接池管理
├── requirements.txt
└── config.py             # 配置文件

使用 Pydantic 做数据验证

这是 FastAPI 最吸引人的一点:你可以直接通过定义 Pydantic 模型,完成接口的数据校验、序列化等工作。

举个例子,我们要接收用户的注册信息:

from pydantic import BaseModel
from typing import Optional

class UserCreate(BaseModel):
    username: str
    email: str
    age: int
    nickname: Optional[str] = None

然后在接口中使用:

@app.post("/users/")
def create_user(user: UserCreate):
    return {
        "message": "用户创建成功",
        "data": user
    }

一旦传参不符合要求,FastAPI 会自动返回格式错误,根本不需要手动去判断字段类型。


SQLAlchemy 与数据库操作

数据库设计模型-1

我们的项目使用了 SQLAlchemy 来做 ORM 操作(当然也可以换成 Tortoise ORM 或者别的工具),主要是考虑到我们已经有部分历史业务跑在 SQLAlchemy 上,为了统一选型。

下面是一个最基础的模型定义:

# models/user_model.py
from sqlalchemy import Column, Integer, String
from database import Base

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String(50), unique=True)
    email = Column(String(100))

然后我们通过依赖注入方式在接口里使用数据库连接:

# database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "postgresql://user:password@localhost/testdb"

engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

在接口中:

from fastapi import Depends
from sqlalchemy.orm import Session

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

@app.post("/users/add")
def add_user(user: UserCreate, db: Session = Depends(get_db)):
    db_user = User(**user.dict())
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

性能优化与生产部署经验

光写得快还不够,我们还要部署上线、保证性能稳定。

1. 使用 Uvicorn + Gunicorn 多进程部署

本地调试可以用:

uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

生产环境建议使用 gunicorn 启动多个 worker,例如:

gunicorn -w 4 -k uvicorn.workers.UvicornWorker app.main:app

其中 -w 4 表示启动 4 个进程,根据服务器 CPU 核心数量调整。

小贴士:推荐使用 --log-config logging.ini 自定义日志格式,方便排查问题。

2. 使用 Redis 缓存高频读取内容

我们会在某些热点数据上加一层缓存,比如某个用户的基本信息或者一些排行榜数据。FastAPI 对接 Redis 很轻松,可以使用 redis-py 或者 aioredis

3. 使用 Kafka 做异步处理任务

像插入数据库这种耗时的操作,不适合同步处理。我们采用了 Kafka 把事件丢到消息队列,由其他消费者处理写入操作,极大提升了整体吞吐量。


踩过的坑和解决过程

🔥 坑一:Pydantic 数据类型转换出错

有时候传进来的是字符串 '1',但我们期望的是整数 age: int,这时候默认不会报错,而是会隐式转换成 int('1') => 1。但在某些场景我们其实更希望严格拒绝非整数输入。

解决办法:使用 StrictInt 类型,强制校验数据格式:

from pydantic import Field, StrictInt

class UserCreate(BaseModel):
    age: StrictInt

⚠️ 坑二:多线程访问数据库连接出错

我们在一个接口里同时发起多个数据库请求,出现报错:

“This Session is already in use by another thread”

原因:SQLAlchemy 默认不是线程安全的。

解决方案

  • 使用 AsyncIO + asyncpg + async SQLAlchemy(如果你走异步路线)
  • 不要在异步函数里混用普通的阻塞 IO
  • 或者采用独立 SessionPool 分配机制

❗ 坑三:Swagger 文档没有更新

有时候新增了接口,或者修改了参数名,文档没更新。

解决方法:重启服务或者确保模型和路由正确导入。


接口设计的经验总结

接口设计是整个后端开发的核心之一,FastAPI 让这件事变得优雅又高效。

建议遵循 RESTful 设计风格

方法 URL 示例 功能说明
GET /users/1 获取单个用户
GET /users?username=admin 查询用户列表
POST /users 创建用户
PUT /users/1 完整更新用户信息
PATCH /users/1 部分更新用户信息
DELETE /users/1 删除用户

统一响应格式

建议所有接口统一返回结构,比如:

{
  "code": 0,
  "message": "success",
  "data": {...}
}

我们可以封装一个全局的 ResponseHandler 中间件:

class ApiResponse:
    @staticmethod
    def success(data=None):
        return {
            "code": 0,
            "message": "success",
            "data": data or {}
        }

    @staticmethod
    def error(message="system error", code=-1):
        return {
            "code": code,
            "message": message
        }

为什么推荐 FastAPI 成为你的首选后端框架

现在整个技术圈都在往云原生、异步、高性能方向发展。FastAPI 几乎天然契合这些趋势,特别是以下几个方面:

  • 原生支持异步编程模型:让你轻松写出高性能 API。
  • 现代化的设计理念:比如自动文档、类型校验、依赖注入、模块化清晰。
  • 社区活跃:越来越多的开发者涌入,配套工具链也越来越完善。
  • 易学习、好上手:对于新手来说,理解成本低,上手快。
  • 适合做微服务架构的基础组件:可以和其他服务(如 Java、Go 服务)无缝对接。

写在最后:FastAPI 学习建议

这是我作为一个老后端的一些肺腑之言,希望能帮到你:

  1. 多动手:别光看文档,一定要动手写一遍完整的项目;
  2. 模拟真实场景:比如模拟订单系统、用户中心、支付回调等;
  3. 尝试接入真实数据库和中间件:别只停留在内存模拟;
  4. 了解背后的原理:比如 ASGI、Starlette、Pydantic 是怎么工作的;
  5. 关注开源项目:GitHub 上有很多优秀的 FastAPI 项目模板,可以作为参考;
  6. 养成良好的编码习惯:模块划分清晰、命名规范、文档完整。

FastAPI 是一个非常适合初学者入门的框架,也是值得深入研究的技术栈。无论你是想转行、跳槽、还是提升技能,掌握 FastAPI 都将是一笔宝贵的财富。


结语:写代码是一种修行

说实话,写了这么多年代码,我发现技术本身并不难,难的是坚持和持续改进的心态。每当我看到新人踩我踩过的坑,我就特别有感触:技术成长从来都不是线性的,而是在一个个坑里摔出来的。

希望你能从这篇文章中少走弯路,早点写出自己的第一个 FastAPI 服务。加油吧,未来可期 😎


如果你觉得这篇文章对你有帮助,欢迎点赞收藏,也可以留言交流你在学习中遇到的问题。让我们一起成长,一起进步!

评论 0

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