FastAPI 是一个现代、高性能的 Python Web 框架,基于 Starlette 和 Pydantic,专为构建 API 而生。它具备自动生成交互式文档 、基于 Python 类型提示的数据校验 、异步支持等强大特性。本文将以一个完整的示例项目为线索,从项目结构、路由管理、请求/响应模型到中间件配置,全方位讲解 FastAPI 的核心用法。
已开源到ai-demo,欢迎star~
一、项目结构概览
fastapi/
├── main.py # 应用入口 & FastAPI 实例创建
├── api/
│ ├── __init__.py # 包标识
│ └── routers.py # API 路由定义
└── models/
└── hello_models.py # Pydantic 请求/响应模型
采用分层架构的思路:
main.py--- 应用层,负责创建 FastAPI 实例、注册中间件和路由。api/--- 接口层,存放所有路由端点。models/--- 数据层,定义 Pydantic 模型,实现请求校验与响应格式化。
二、入口文件:创建 FastAPI 应用
python
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from api.routers import api_router
app = FastAPI(
title="My DeepAgents API",
description="This is My DeepAgents API",
version="0.1.0"
)
2.1 FastAPI 实例化参数
| 参数 | 说明 |
|---|---|
title |
API 文档标题(显示在 Swagger UI / ReDoc 顶部) |
description |
API 的详细描述,支持 Markdown |
version |
API 版本号,建议遵循语义化版本规范 |
这三个参数会直接反映在自动生成的 /docs 和 /redoc 接口文档中。
2.2 启动服务
bash
uvicorn main:app --reload
main:app→main.py中的app实例(FastAPI 类型)。--reload→ 开发模式,代码修改后自动重启(生产环境请去掉该参数)。
启动后访问:
- 交互式文档 :
http://localhost:8000/docs - 备用文档 :
http://localhost:8000/redoc
三、CORS 跨域中间件配置
python
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000", "http://localhost:8080"],
allow_methods=["GET", "POST"],
allow_headers=["*"]
)
3.1 参数详解
| 参数 | 说明 |
|---|---|
allow_origins |
允许跨域的前端源列表 。生产环境应指定具体域名,避免使用 ["*"] |
allow_methods |
允许的 HTTP 方法,如 ["GET", "POST", "PUT", "DELETE"] |
allow_headers |
允许的请求头,["*"] 表示允许所有 |
最佳实践 :开发阶段可宽松配置,上线后应严格限制
allow_origins为明确的前端地址。
四、路由管理:APIRouter 的使用
python
# api/routers.py
from fastapi import APIRouter
api_router = APIRouter()
APIRouter 可以将路由从主应用中解耦出来,便于大型项目的模块化管理。
4.1 注册路由到主应用
python
# main.py
app.include_router(api_router, prefix="/api")
| 参数 | 说明 |
|---|---|
api_router |
要注册的路由器实例 |
prefix="/api" |
为该路由器下所有端点添加统一的 URL 前缀 |
此时,api_router 中定义的 /hello 实际访问路径变为 /api/hello。
五、端点定义:GET / POST 多种传参方式
5.1 最简单的 GET 请求
python
@api_router.get("/")
async def root():
return {"message": "This is a FastAPI server!"}
bash
curl http://localhost:8000/api/
# 返回: {"message": "This is a FastAPI server!"}
5.2 GET 请求返回 JSON
python
@api_router.get("/hello", tags=["helloTag"])
async def hello():
"""
处理 GET /api/hello 请求,返回欢迎消息。
"""
return {"message": "Hello, World!"}
tags=["helloTag"]--- 在 Swagger 文档中将该端点归入helloTag分组,方便查找。- docstring 会直接显示在 Swagger 文档的端点描述中,建议养成写文档字符串的习惯。
bash
curl http://localhost:8000/api/hello
# 返回: {"message": "Hello, World!"}
5.3 POST 请求 --- 查询参数传参
python
@api_router.post("/hello", tags=["helloTag"])
async def hello_post(name: str = "World"):
return {"message": f"POST response> Hello, {name}!"}
FastAPI 会自动根据函数签名推断参数来源:
- 基础类型参数(
str、int等)默认从查询参数获取。
调用方式一:URL 查询参数
bash
curl -X POST "http://localhost:8000/api/hello?name=rick"
# 返回: {"message": "POST response> Hello, rick!"}
调用方式二:JSON Body
bash
curl -X POST "http://localhost:8000/api/hello" \
-H "Content-Type: application/json" \
-d '{"name": "rick"}'
# 返回: {"message": "POST response> Hello, rick!"}
调用方式三:表单数据
bash
curl -X POST "http://localhost:8000/api/hello" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'name=rick'
# 返回: {"message": "POST response> Hello, rick!"}
要点:FastAPI 对于基础类型参数,会智能地从 query、body、form 三种来源中解析,极大提升了灵活性。
六、Pydantic 模型:请求校验 & 响应格式化
这是 FastAPI 最核心的特性之一。可以把数据模型定义在 models/hello_models.py 中。
6.1 定义请求体模型
python
# models/hello_models.py
from pydantic import BaseModel, Field
class HelloRequest(BaseModel):
name: str = Field(default="World", description="用户名")
| 要素 | 说明 |
|---|---|
BaseModel |
Pydantic 基类,继承后自动获得校验、序列化能力 |
Field(default="World") |
默认值为 "World",客户端不传则自动填充 |
Field(description="...") |
字段说明,会显示在 Swagger 文档的 Schema 中 |
6.2 响应用模型
python
class HelloResponse(BaseModel):
message: str = Field(description="欢迎消息")
6.3 在端点中使用请求模型
python
@api_router.post("/hello_model", tags=["helloTag"])
async def hello_post_model(request: HelloRequest):
return {"message": f"POST Model response> Hello, {request.name}!"}
- 参数类型标注为
HelloRequest,FastAPI 会自动:- 将请求体 JSON 反序列化为
HelloRequest实例。 - 校验字段类型、必填性。
- 校验失败时返回
422 Unprocessable Entity,并给出详细的错误信息。
- 将请求体 JSON 反序列化为
正确的请求
bash
curl -X POST "http://localhost:8000/api/hello_model" \
-H "Content-Type: application/json" \
-d '{"name": "rick"}'
# 返回: {"message": "POST Model response> Hello, rick!"}
不传 name(使用默认值)
bash
curl -X POST "http://localhost:8000/api/hello_model" \
-H "Content-Type: application/json" \
-d '{}'
# 返回: {"message": "POST Model response> Hello, World!"}
传入错误类型(触发自动校验)
bash
curl -X POST "http://localhost:8000/api/hello_model" \
-H "Content-Type: application/json" \
-d '{"name": 123}'
# 返回 422,提示 name 应为字符串
6.4 使用 response_model 控制输出
python
@api_router.post("/hello_full_model", tags=["helloTag"],
response_model=HelloResponse)
async def hello_full_model(request: HelloRequest):
return HelloResponse(
message=f"POST Full Model response> Hello, {request.name}!"
)
| 特性 | 说明 |
|---|---|
| 请求校验 | request: HelloRequest 校验输入 |
| 响应过滤 | response_model=HelloResponse 确保输出只包含模型定义的字段,自动屏蔽多余字段 |
| 文档生成 | Swagger 文档中自动展示响应 Schema,前后端协作更高效 |
| 数据转换 | 即使返回 dict,FastAPI 也会按 response_model 进行转换和校验 |
bash
curl -X POST "http://localhost:8000/api/hello_full_model" \
-H "Content-Type: application/json" \
-d '{"name": "FastAPI"}'
# 返回: {"message": "POST Full Model response> Hello, FastAPI!"}
七、完整调用示例汇总
| 端点 | 方法 | 路径 | 请求方式 | curl 命令 |
|---|---|---|---|---|
| root | GET | /api/ |
无参 | curl http://localhost:8000/api/ |
| hello | GET | /api/hello |
无参 | curl http://localhost:8000/api/hello |
| hello | POST | /api/hello |
query/body/form | curl -X POST "http://localhost:8000/api/hello?name=rick" |
| hello_model | POST | /api/hello_model |
JSON body | curl -X POST "http://localhost:8000/api/hello_model" -H "Content-Type: application/json" -d '{"name":"rick"}' |
| hello_full_model | POST | /api/hello_full_model |
JSON body + 模型响应 | curl -X POST "http://localhost:8000/api/hello_full_model" -H "Content-Type: application/json" -d '{"name":"FastAPI"}' |
八、Swagger 文档实战
启动服务后访问 http://localhost:8000/docs,你会看到:
- 分组标签 --- 所有标注
tags=["helloTag"]的端点归入同一组,折叠管理更清爽。 - 端点描述 --- 每个函数的 docstring 会作为端点说明展示。
- 参数说明 ---
Field(description=...)的内容会作为字段提示。 - 在线调试 --- 点击 "Try it out" 按钮,直接在浏览器中发送请求并查看响应。
这就是 FastAPI "文档即代码" 理念的体现 --- 你写的类型提示和 docstring,自动生成了完整的 API 文档。
九、最佳实践总结
9.1 项目结构
- 小型项目 :
main.py+models.py即可。 - 中大型项目 :按功能拆分
routers/、models/、services/、schemas/等模块。
9.2 模型使用
- 务必使用 Pydantic 模型定义请求体和响应体,避免手工解析 JSON。
- 为每个端点单独定义请求/响应模型,保持接口契约清晰。
- 利用
Field(description=...)为字段添加说明,提升文档质量。
9.3 路由管理
- 使用
APIRouter拆分路由,按业务模块组织(如users.py、orders.py)。 - 统一使用
prefix避免路径重复。
9.4 文档与注释
- 为每个端点写清晰的 docstring,它会直接呈现在 Swagger 文档中。
tags用于分组,response_model用于声明响应格式。
9.5 生产环境注意事项
- 去掉
--reload参数,改用gunicorn + uvicorn workers。 - 严格限制
allow_origins,禁止使用["*"]。 - 添加认证中间件(如 JWT、OAuth2)。