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 应用

# 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 启动服务

uvicorn main:app --reload
  • main:appmain.py 中的 app 实例(FastAPI 类型)。
  • --reload → 开发模式,代码修改后自动重启(生产环境请去掉该参数)。

启动后访问:

  • 交互式文档http://localhost:8000/docs
  • 备用文档http://localhost:8000/redoc

三、CORS 跨域中间件配置

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 的使用

# api/routers.py
from fastapi import APIRouter

api_router = APIRouter()

APIRouter 可以将路由从主应用中解耦出来,便于大型项目的模块化管理。

4.1 注册路由到主应用

# main.py
app.include_router(api_router, prefix="/api")
参数 说明
api_router 要注册的路由器实例
prefix="/api" 为该路由器下所有端点添加统一的 URL 前缀

此时,api_router 中定义的 /hello 实际访问路径变为 /api/hello


五、端点定义:GET / POST 多种传参方式

5.1 最简单的 GET 请求

@api_router.get("/")
async def root():
    return {"message": "This is a FastAPI server!"}
curl http://localhost:8000/api/
# 返回: {"message": "This is a FastAPI server!"}

5.2 GET 请求返回 JSON

@api_router.get("/hello", tags=["helloTag"])
async def hello():
    """
    处理 GET /api/hello 请求,返回欢迎消息。
    """
    return {"message": "Hello, World!"}
  • tags=["helloTag"] — 在 Swagger 文档中将该端点归入 helloTag 分组,方便查找。
  • docstring 会直接显示在 Swagger 文档的端点描述中,建议养成写文档字符串的习惯。
curl http://localhost:8000/api/hello
# 返回: {"message": "Hello, World!"}

5.3 POST 请求 — 查询参数传参

@api_router.post("/hello", tags=["helloTag"])
async def hello_post(name: str = "World"):
    return {"message": f"POST response> Hello, {name}!"}

FastAPI 会自动根据函数签名推断参数来源:

  • 基础类型参数(strint 等)默认从查询参数获取。
调用方式一:URL 查询参数
curl -X POST "http://localhost:8000/api/hello?name=rick"
# 返回: {"message": "POST response> Hello, rick!"}
调用方式二:JSON Body
curl -X POST "http://localhost:8000/api/hello" \
  -H "Content-Type: application/json" \
  -d '{"name": "rick"}'
# 返回: {"message": "POST response> Hello, rick!"}
调用方式三:表单数据
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 定义请求体模型

# 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 响应用模型

class HelloResponse(BaseModel):
    message: str = Field(description="欢迎消息")

6.3 在端点中使用请求模型

@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 会自动:
    1. 将请求体 JSON 反序列化为 HelloRequest 实例。
    2. 校验字段类型、必填性。
    3. 校验失败时返回 422 Unprocessable Entity,并给出详细的错误信息。
正确的请求
curl -X POST "http://localhost:8000/api/hello_model" \
  -H "Content-Type: application/json" \
  -d '{"name": "rick"}'
# 返回: {"message": "POST Model response> Hello, rick!"}
不传 name(使用默认值)
curl -X POST "http://localhost:8000/api/hello_model" \
  -H "Content-Type: application/json" \
  -d '{}'
# 返回: {"message": "POST Model response> Hello, World!"}
传入错误类型(触发自动校验)
curl -X POST "http://localhost:8000/api/hello_model" \
  -H "Content-Type: application/json" \
  -d '{"name": 123}'
# 返回 422,提示 name 应为字符串

6.4 使用 response_model 控制输出

@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 进行转换和校验
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,你会看到:

  1. 分组标签 — 所有标注 tags=["helloTag"] 的端点归入同一组,折叠管理更清爽。
  2. 端点描述 — 每个函数的 docstring 会作为端点说明展示。
  3. 参数说明Field(description=...) 的内容会作为字段提示。
  4. 在线调试 — 点击 “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.pyorders.py)。
  • 统一使用 prefix 避免路径重复。

9.4 文档与注释

  • 为每个端点写清晰的 docstring,它会直接呈现在 Swagger 文档中。
  • tags 用于分组,response_model 用于声明响应格式。

9.5 生产环境注意事项

  • 去掉 --reload 参数,改用 gunicorn + uvicorn workers
  • 严格限制 allow_origins,禁止使用 ["*"]
  • 添加认证中间件(如 JWT、OAuth2)。

十、参考资料


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐