FastAPI 教程(超详细)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在当今互联网时代,构建高效且可维护的 API 已成为开发者的核心需求。FastAPI 作为 Python 生态中新兴的异步框架,凭借其高性能、自动文档生成功能和直观的代码风格,迅速成为开发者们的热门选择。本文将通过循序渐进的方式,为编程初学者和中级开发者提供一份详尽的 FastAPI 教程,涵盖从环境搭建到实战部署的全流程,并穿插形象化比喻和代码示例,帮助读者轻松掌握这一工具。
一、FastAPI 的核心优势与适用场景
1.1 为什么选择 FastAPI?
FastAPI 的核心设计理念可以概括为三个关键词:快速、开发者友好和类型驱动。
- 快速:FastAPI 基于 Starlette 和 Pydantic,通过异步编程和高性能的底层实现,能够在处理高并发请求时保持低延迟。
- 开发者友好:框架通过类型注解自动生成交互式 API 文档(Swagger UI),并提供直观的错误提示,大幅降低调试成本。
- 类型驱动:通过 Python 的类型提示(Type Hints),FastAPI 能自动校验输入数据格式,减少手动验证的繁琐工作。
1.2 典型应用场景
FastAPI 适用于需要快速搭建 RESTful API 的场景,例如:
- 构建微服务架构中的数据接口
- 开发高并发的实时数据处理服务
- 为移动应用或前端提供后端支持
比喻:如果将 API 比作一座桥梁,FastAPI 就像一座预制装配式桥梁——它通过标准化的组件(如自动文档、类型校验)快速搭建,让开发者无需从头设计每个细节,从而专注于业务逻辑。
二、环境搭建与第一个 API
2.1 安装 FastAPI
通过 pip 可以快速安装 FastAPI 及其依赖项:
pip install fastapi[all]
此命令会安装 FastAPI、Uvicorn(异步服务器)和相关工具包。
2.2 编写第一个“Hello World”
创建文件 main.py
,输入以下代码:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"message": "Hello FastAPI!"}
运行命令 uvicorn main:app --reload
后,访问 http://localhost:8000
,即可看到自动生成的交互式文档,点击右上角的 Try it out 按钮即可测试接口。
三、基础路由与参数处理
3.1 路由定义与 HTTP 方法
FastAPI 支持通过装饰器定义不同 HTTP 方法的路由:
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
@app.post("/items/")
async def create_item(item: dict):
return {"received": item}
@app.get
对应 GET 请求,用于获取资源。@app.post
对应 POST 请求,用于创建资源。
3.2 路径参数与查询参数
3.2.1 路径参数
通过 {}
定义动态路径参数,例如:
@app.get("/users/{user_id}")
async def read_user(user_id: str):
return {"user_id": user_id}
访问 http://localhost:8000/users/123
时,user_id
的值会被自动提取为字符串。
3.2.2 查询参数
通过函数参数直接接收查询参数:
@app.get("/search")
async def search(q: str = None, limit: int = 10):
return {"query": q, "limit": limit}
访问 http://localhost:8000/search?q=hello&limit=5
时,参数会被自动映射。
四、数据验证与序列化:Pydantic 的力量
4.1 Pydantic 模型基础
FastAPI 通过 Pydantic 的数据模型定义输入输出格式。例如,定义一个 Item
模型:
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
is_offer: bool = False
在路由中使用该模型:
@app.post("/items/")
async def create_item(item: Item):
return item
此时,FastAPI 会自动校验请求体是否符合 Item
的字段要求,并返回友好错误提示。
4.2 嵌套模型与复杂数据结构
Pydantic 支持嵌套模型,例如:
class User(BaseModel):
id: int
name: str
class Order(BaseModel):
user: User
items: list[Item]
通过这种方式,可以轻松定义多层级的数据结构。
五、异步编程与并发处理
5.1 异步函数的定义
FastAPI 支持原生异步函数,通过 async def
声明:
@app.get("/async")
async def read_async():
await some_async_operation() # 模拟异步操作
return {"status": "done"}
5.2 并发请求的优化
假设有一个需要调用外部 API 的场景:
import httpx
async def fetch_data():
async with httpx.AsyncClient() as client:
response = await client.get("https://api.example.com/data")
return response.json()
@app.get("/external")
async def read_external():
data = await fetch_data()
return data
通过异步 HTTP 客户端(如 httpx
),可以避免阻塞其他请求,提升吞吐量。
比喻:同步编程如同排队点餐,每人必须等待前一位完成;而异步编程如同多线程服务,服务员可以同时处理多个订单,减少等待时间。
六、依赖注入与请求校验
6.1 依赖注入(Dependency Injection)
通过 Depends
实现代码复用和逻辑解耦:
def verify_token(token: str = Depends(oauth2_scheme)):
# 实现令牌验证逻辑
return user
@app.get("/protected")
async def protected_route(current_user: User = Depends(verify_token)):
return {"user": current_user}
6.2 请求体校验与默认值
结合 Pydantic 模型和默认值:
class UpdateItem(BaseModel):
name: str | None = None
price: float | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: UpdateItem):
stored_item = {"name": "default", "price": 0.0}
updated_item = stored_item.copy()
if item.name is not None:
updated_item["name"] = item.name
if item.price is not None:
updated_item["price"] = item.price
return updated_item
七、实战案例:构建一个待办事项(Todo)API
7.1 需求分析
实现一个支持增删改查的 Todo 列表,包含以下功能:
- 创建任务(POST)
- 获取所有任务(GET)
- 更新任务(PUT)
- 删除任务(DELETE)
7.2 代码实现
7.2.1 数据模型
class TodoItem(BaseModel):
id: int
title: str
completed: bool = False
7.2.2 路由定义
todos = [] # 模拟内存数据库
@app.post("/todos/")
async def create_todo(item: TodoItem):
todos.append(item)
return {"status": "success", "data": item}
@app.get("/todos/")
async def read_todos():
return {"todos": todos}
@app.put("/todos/{item_id}")
async def update_todo(item_id: int, item: TodoItem):
for i in range(len(todos)):
if todos[i].id == item_id:
todos[i] = item
return {"status": "updated"}
return {"error": "Item not found"}
@app.delete("/todos/{item_id}")
async def delete_todo(item_id: int):
global todos
todos = [item for item in todos if item.id != item_id]
return {"status": "deleted"}
八、部署与性能优化
8.1 部署到生产环境
推荐使用 Uvicorn 结合 Nginx 或 Caddy 作为反向代理。例如:
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
8.2 性能调优建议
- 启用 HTTP/2:在 Uvicorn 中添加
--http=httptools
参数。 - 缓存策略:使用
@cache
装饰器或第三方库(如 FastAPICache)。 - 数据库连接池:通过异步数据库驱动(如 asyncpg)优化数据库交互。
结论
通过本文的 FastAPI 教程,读者已掌握了从环境搭建到实战部署的全流程,并理解了 FastAPI 在类型校验、异步编程和自动化文档方面的核心优势。无论是构建小型项目还是处理高并发需求,FastAPI 都能提供高效且优雅的解决方案。建议读者通过实践案例不断巩固知识,并参考官方文档探索更高级功能(如 WebSocket、OAuth2 认证等)。掌握 FastAPI,你将能够快速构建现代化、可维护的 API 服务,为后续的微服务架构或全栈开发打下坚实基础。