FastAPI入门:Python后端开发新手指南
去年十月,我裸辞了。
在某大厂卷了三年,从“还能再肝”到“一听见钉钉响就手抖”,最后终于在双11大促前一周递了辞职信——不是因为被裁,纯粹是精神快崩了。Gap这半年,前两个月躺平打《艾尔登法环》,中间两个月学Go(别问,问就是看隔壁Golang岗位薪资高),后两个月疯狂刷LeetCode,准备重新杀回职场。结果简历投出去才发现:现在招Python后端的岗位,十有八九写着“熟悉FastAPI优先”。
我寻思着,以前在公司天天用Flask/Django,FastAPI不就是个“快一点的API框架”吗?直到上周五晚上,我模拟面试时被问到:“你们项目为什么选FastAPI而不是Flask?它在性能和类型安全上做了哪些优化?”——我当场卡壳,支支吾吾说了句“因为它快”,面试官沉默了三秒,然后说:“好的,我们再联系。”
那一刻,我真的想砸电脑。
于是痛定思痛,花了整整一周时间,从零搭建、压测、部署一个完整的FastAPI服务,顺便把那些面试题、简历亮点、系统设计细节都捋清楚了。今天这篇,就是给像我一样“以为自己会Python就能写后端”的兄弟姐妹们,一份血泪换来的实战指南。
为什么是FastAPI?别再只说“因为它快”了
很多人(包括曾经的我)对FastAPI的理解停留在“比Flask快”。这没错,但太浅了。真正让大厂偏爱FastAPI的,是它在“开发效率”和“运行时可靠性”之间的平衡。
回想我在前司的日子,每次改接口都要手动写Swagger文档,产品经理拿着PRD过来问:“这个字段到底是int还是string?”——我翻半天代码才敢回答。测试同学更惨,没有强类型约束,传个"null"字符串进来,后端直接500,锅还得我背。
FastAPI不一样。它基于Python 3.7+的类型注解(Type Hints)和 Pydantic 模型,自动做请求校验、生成OpenAPI文档、甚至支持异步。这意味着:
- 接口定义即文档(再也不用手动维护Swagger)
- 请求参数错了?直接422返回详细错误,不用进日志查
- 异步支持原生集成(比如调外部API、读数据库可以不阻塞)
而且性能确实能打。官方Benchmark显示,FastAPI在纯JSON响应场景下,吞吐量接近Go的Gin框架(虽然Go整体还是更快,但Python能到这个水平已经很顶了)。对于我们这些不想写Go但又想要高性能的人来说,简直是救命稻草。
说真的,学Go那两个月我差点放弃Python生态。但FastAPI让我意识到:语言只是工具,架构和设计才是核心。只要用对框架,Python照样能扛住高并发。
动手!从零搭建一个“面试题管理”API
为了模拟真实场景,我决定做一个“算法面试题管理系统”——毕竟我现在天天刷题,顺手造个轮子还能写进简历。需求很简单:
- 创建/查询/更新/删除面试题(题目、标签、难度、解答)
- 支持按标签或难度筛选
- 接口要快、要稳、要有文档
第一步:环境与依赖
我习惯用VSCode,插件装了一堆:Python、Pylance、REST Client、Error Lens……特别是Error Lens,能实时标红类型错误,配合FastAPI简直绝配。
新建项目,requirements.txt如下:
fastapi==0.104.1
uvicorn[standard]==0.24.0
pydantic==2.5.0
sqlalchemy==2.0.23
asyncpg==0.28.0 # 异步PostgreSQL驱动
python-dotenv==1.0.0
注意:别用SQLite做生产演示!很多教程用SQLite图省事,但实际工作中几乎没人用它跑后端服务。我这里直接上PostgreSQL + 异步驱动,贴近真实环境。
启动命令也简单:
uvicorn main:app --reload --port 8000
--reload 是开发神器,代码一改自动重启。但上线记得关掉,不然内存爆炸。
第二步:定义数据模型(Pydantic + SQLAlchemy)
这是FastAPI最爽的地方:请求体、响应体、数据库模型可以高度复用。
先定义Pydantic模型(用于校验和序列化):
# schemas.py
from pydantic import BaseModel
from typing import List, Optional
class InterviewQuestionBase(BaseModel):
title: str
description: str
difficulty: str # 'easy', 'medium', 'hard'
tags: List[str]
class InterviewQuestionCreate(InterviewQuestionBase):
pass
class InterviewQuestion(InterviewQuestionBase):
id: int
solved_count: int = 0
class Config:
from_attributes = True # 替代旧版orm_mode
再定义SQLAlchemy模型(用于数据库操作):
# models.py
from sqlalchemy import Column, Integer, String, Text
from sqlalchemy.dialects.postgresql import ARRAY
from database import Base
class InterviewQuestionDB(Base):
__tablename__ = "interview_questions"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(Text)
difficulty = Column(String)
tags = Column(ARRAY(String)) # PostgreSQL特有,存标签数组
solved_count = Column(Integer, default=0)
看到没?Pydantic负责“对外交互”,SQLAlchemy负责“对内存储”,职责分离得明明白白。而且from_attributes = True让Pydantic能直接从ORM对象转成字典,省去手动映射。
吐槽一下:以前用Flask-SQLAlchemy,经常要写
to_dict()方法,重复代码多到想哭。FastAPI这套组合拳,直接把样板代码砍掉80%。
第三步:写路由(别忘了异步!)
核心逻辑来了。假设我们要实现“创建题目”和“按标签查询”:
# main.py
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from database import get_db
from crud import create_question, get_questions_by_tag
from schemas import InterviewQuestion, InterviewQuestionCreate
app = FastAPI(title="算法面试题API", version="1.0")
@app.post("/questions/", response_model=InterviewQuestion)
async def create_interview_question(
question: InterviewQuestionCreate,
db: AsyncSession = Depends(get_db)
):
return await create_question(db, question)
@app.get("/questions/", response_model=list[InterviewQuestion])
async def read_questions_by_tag(
tag: str,
db: AsyncSession = Depends(get_db)
):
questions = await get_questions_by_tag(db, tag)
if not questions:
raise HTTPException(status_code=404, detail="No questions found")
return questions
关键点:
- 所有函数加
async,数据库操作也用异步(AsyncSession) Depends(get_db)自动管理数据库连接生命周期response_model强制返回结构,避免意外泄露字段(比如密码)
有一次我在前司的接口里不小心把
user.password_hash返回了,虽然没明文,但还是被安全团队call去喝茶。FastAPI的response_model相当于一道保险,编译期(其实是启动时)就检查结构,防呆效果一流。
第四步:数据库操作(异步CRUD)
用SQLAlchemy 2.0的异步风格写CRUD:
# crud.py
from sqlalchemy.future import select
from sqlalchemy.ext.asyncio import AsyncSession
from models import InterviewQuestionDB
from schemas import InterviewQuestionCreate
async def create_question(db: AsyncSession, question: InterviewQuestionCreate):
db_question = InterviewQuestionDB(**question.model_dump())
db.add(db_question)
await db.commit()
await db.refresh(db_question)
return db_question
async def get_questions_by_tag(db: AsyncSession, tag: str):
result = await db.execute(
select(InterviewQuestionDB).where(InterviewQuestionDB.tags.contains([tag]))
)
return result.scalars().all()
注意:tags.contains([tag]) 是PostgreSQL的数组查询语法,超方便。如果是MySQL就得用LIKE或者单独建关联表,麻烦多了。
踩坑实录:那些文档不会告诉你的事
坑1:异步上下文管理器别乱用
一开始我图省事,直接在路由里写:
# 错误示范!
async with async_session() as session:
...
结果压力测试时发现连接池爆了。正确做法是用Depends注入session,让FastAPI自动管理生命周期。否则每个请求都新建连接,数据库直接跪。
坑2:Pydantic v2 的 breaking change
Pydantic 2.0 把 orm_mode = True 改成了 from_attributes = True,很多老教程没更新,照抄直接报错。升级依赖前务必看CHANGELOG!
坑3:CORS 配置漏了,前端调不通
本地开发时,前端(比如React)跑在3000端口,FastAPI在8000,跨域直接被浏览器拦了。加个中间件就行:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
但上线时一定要限制allow_origins,别写["*"],否则有安全风险。
性能实测:FastAPI vs Flask vs Go Gin
为了说服自己(和未来的面试官),我做了简单压测。环境:MacBook Pro M1, 16GB RAM。
| 框架 | 并发100 | RPS (Requests/sec) | 平均延迟 |
|---|---|---|---|
| FastAPI | ✅ | 3200 | 31ms |
| Flask | ✅ | 850 | 118ms |
| Go Gin | ✅ | 9800 | 10ms |
测试脚本用
wrk -t12 -c100 -d30s http://localhost:8000/questions/?tag=array
结论很清晰:
- FastAPI 比传统Flask快近4倍(主要归功于异步和Starlette底层)
- 但Go依然碾压(语言层面的优势没法比)
- 不过对于大多数业务场景,FastAPI的3200 RPS完全够用——除非你是抖音后端
所以别盲目转Go。如果你团队主力是Python,用FastAPI能把性能瓶颈从“框架”转移到“业务逻辑优化”上,ROI更高。
写进简历的亮点怎么包装?
现在你知道技术细节了,但怎么让HR和面试官眼前一亮?我的建议:
- 别写“使用FastAPI开发后端服务”(太泛)
- 要写“基于FastAPI构建高可用面试题API,QPS达3000+,通过Pydantic实现全链路类型安全,减少线上参数错误90%”
具体话术参考:
主导重构内部工具后端,采用FastAPI + SQLAlchemy 2.0异步方案,接口平均响应时间从120ms降至35ms;利用Pydantic自动校验与OpenAPI文档生成,降低前后端联调成本40%;设计PostgreSQL数组字段存储多标签,支持毫秒级筛选。
看出来没?数字 + 技术关键词 + 业务价值,三位一体。
最后:FastAPI适合你吗?
如果你符合以下任一:
- 正在准备跳槽,简历需要“现代化Python后端”项目
- 团队还在用Flask/Django,想提升开发体验
- 被类型错误折磨到想转行
那FastAPI绝对值得一试。
它不是银弹(比如复杂业务逻辑还是得靠领域建模),但它能让你在“快速交付”和“代码质量”之间找到甜蜜点。对我这种Gap后重回职场的人来说,用FastAPI写出来的项目,既有技术深度,又能体现工程素养——面试时聊起来底气都足了。
哦对了,上周我又面了一家公司。当面试官问起FastAPI优势时,我直接掏出这篇笔记(开玩笑的),然后侃了十分钟类型系统、异步非阻塞、还有那个PostgreSQL数组查询的骚操作。最后他说:“你这理解比我们现任后端还深。”
那一刻,我知道:裸辞的gap半年,值了。
附:快速上手清单
- 用
uvicorn启动,别用python main.py - 所有数据库操作走异步(
AsyncSession) - Pydantic模型严格定义输入输出
- 生产环境关掉
--reload,用Gunicorn + Uvicorn workers - 加CORS中间件(开发时)
- 用
/docs自动生成API文档,别手写!
祝大家都能写出又快又稳的API,拿到心仪offer。下次面试,别再说“因为它快”了 😉

评论 0