FastAPI 入门:Python 后端开发新手指南
引言:我是怎么开始用 FastAPI 的?

我是一个干了五年后端的 Python 工程师,经历过从 Flask、Django 到现在的 FastAPI。坦白讲,刚接触 FastAPI 的时候,我还挺抵触的。心想:“这玩意儿看起来不就是个新瓶装旧酒的小轮子吗?”结果一次项目实战让我彻底改变了看法。
事情是这样的,那会我们团队要启动一个新的内部服务,需要支持高并发、快速上线、接口文档自动化这些需求。一开始我们还想用熟悉的 Django + DRF(Django REST Framework),但是因为性能瓶颈的问题,加上文档生成这块还是需要额外配置,最后决定试试看社区讨论很多的 FastAPI。
这一试不要紧,一发不可收拾。FastAPI 确实让我感受到了什么叫“现代”、“高效”,并且它天生就适合做 API 服务。
所以今天我想结合自己真实的项目经历,来写一篇给新手的《FastAPI 入门指南》,希望对刚入坑 Python 后端的你有所帮助。
我们当时遇到的问题

我们的项目是一个内部的用户行为采集系统。简单点说,就是前端每次触发一个事件(比如点击、浏览页面等),都需要通过 HTTP 请求发送到后端,进行数据入库和处理。项目要求如下:
- 高并发请求支持
- 接口文档自动生成,方便前后端协作
- 数据校验严格,避免脏数据
- 性能不能太差,最好接近 Go、Node.js 这类语言水平(当然不能完全比,但至少不要太慢)
为什么 Django 不够用了?
Django 是个很成熟、功能齐全的框架,但是在这种以轻量级 API 为主的场景下:
- 初始化较重:尤其是 ORM 和中间件加载,启动时间长;
- 异步支持不够原生:虽然 Django 支持 async,但还不是第一优先级;
- 文档生成需要手动维护或引入 Swagger 扩展;
- 性能问题:在面对几万 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 与数据库操作

我们的项目使用了 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 学习建议
这是我作为一个老后端的一些肺腑之言,希望能帮到你:
- 多动手:别光看文档,一定要动手写一遍完整的项目;
- 模拟真实场景:比如模拟订单系统、用户中心、支付回调等;
- 尝试接入真实数据库和中间件:别只停留在内存模拟;
- 了解背后的原理:比如 ASGI、Starlette、Pydantic 是怎么工作的;
- 关注开源项目:GitHub 上有很多优秀的 FastAPI 项目模板,可以作为参考;
- 养成良好的编码习惯:模块划分清晰、命名规范、文档完整。
FastAPI 是一个非常适合初学者入门的框架,也是值得深入研究的技术栈。无论你是想转行、跳槽、还是提升技能,掌握 FastAPI 都将是一笔宝贵的财富。
结语:写代码是一种修行
说实话,写了这么多年代码,我发现技术本身并不难,难的是坚持和持续改进的心态。每当我看到新人踩我踩过的坑,我就特别有感触:技术成长从来都不是线性的,而是在一个个坑里摔出来的。
希望你能从这篇文章中少走弯路,早点写出自己的第一个 FastAPI 服务。加油吧,未来可期 😎
如果你觉得这篇文章对你有帮助,欢迎点赞收藏,也可以留言交流你在学习中遇到的问题。让我们一起成长,一起进步!

评论 0