FastAPI 入门指南 :基础概念与核心特性

一. FastAPI 简介

1.1 什么是 FastAPI

FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框架,专为在 Python 中构建 RESTful API 而设计。它使用 Python 3.8 + 并基于标准的 Python 类型提示,建立在 Starlette 和 Pydantic 之上

技术栈基础:​

  • Starlette:轻量级 ASGI 框架,提供异步支持
  • Pydantic:数据验证和设置管理库
  • OpenAPI:API 文档标准
  • Python 类型提示:代码提示和验证

1.2 FastAPI 的核心特点

🚀 卓越性能​

  • 基于异步编程模型,性能接近 Node.js 和 Go
  • 支持并发请求处理
  • 低延迟和高吞吐量

📝 自动文档生成​

  • 自动生成交互式 API 文档
  • 支持 Swagger UI 和 ReDoc 两种风格
  • 基于 OpenAPI 3.0 规范

🎯 强大的类型支持​

  • 利用 Python 3.8 + 的类型提示
  • 编译时类型检查
  • 优秀的 IDE 支持和代码提示

🔧 易于使用​

  • 直观的 API 设计
  • 最少的样板代码
  • 快速的开发周期

1.3 适用场景​

  • 前后端分离项目:作为 API 后端服务
  • 微服务架构:独立的服务组件
  • 数据 API:处理和返回 JSON 数据
  • 实时应用:支持 WebSocket 协议
  • 自动化测试:快速构建测试接口

1.4 为什么选择 FastAPI

与其他框架对比:

|------|---------|--------|--------|
| 特性 | FastAPI | Flask | Django |
| 性能 | 极高(异步) | 中等(同步) | 中等(同步) |
| 文档 | 自动生成 | 需要扩展 | 需要扩展 |
| 类型支持 | 原生支持 | 有限支持 | 有限支持 |
| 学习曲线 | 平缓 | 平缓 | 陡峭 |
| 生态系统 | 快速增长 | 非常成熟 | 非常成熟 |

二. 环境搭建与安装

2.1 系统要求​

  • Python 版本:3.8 或更高版本
  • 操作系统:Windows、macOS、Linux 均可
  • 内存:建议至少 1GB(生产环境更多)

2.2 安装方法

(1)使用 pip 安装(推荐)

bash 复制代码
# 基础安装
pip install fastapi

# 安装ASGI服务器(生产环境必需)
pip install uvicorn

# 或者安装所有依赖(包含开发工具)
pip install fastapi[all]

(2)使用 conda 安装

bash 复制代码
conda install -c conda-forge fastapi uvicorn

(3) 验证安装

bash 复制代码
# 检查FastAPI版本
python -c "import fastapi; print(f'FastAPI版本: {fastapi.__version__}')"

# 检查uvicorn版本
python -c "import uvicorn; print(f'Uvicorn版本: {uvicorn.__version__}')"

2.3 开发环境配置

(1) IDE 推荐​

  • PyCharm:完整的 Python 开发环境
  • VS Code:轻量级,丰富的 Python 插件
  • Jupyter Notebook:交互式开发

(2) 项目结构

bash 复制代码
my_fastapi_project/
├── main.py          # 应用入口文件
├── requirements.txt # 依赖列表
├── .gitignore       # Git忽略文件
└── README.md        # 项目说明

三. 第一个 FastAPI 应用

3.1 创建基础应用

创建一个名为 main.py 的文件:

python 复制代码
# main.py
from typing import Union
from fastapi import FastAPI

# 创建FastAPI实例
app = FastAPI(
    title="我的第一个FastAPI应用",
    description="这是一个简单的FastAPI示例",
    version="1.0.0",
)

# 定义根路径的GET请求
@app.get("/")
def read_root():
    """
    根路径接口
    - 描述:返回欢迎信息
    - 方法:GET
    - 返回:JSON格式的欢迎信息
    """
    return {"message": "欢迎使用FastAPI!", "version": "1.0.0"}

# 定义带参数的GET请求
@app.get("/items/{item_id}")
def read_item(
    item_id: int, 
    q: Union[str, None] = None,
    price: float = 0.0
):
    """
    获取商品信息
    - 描述:根据商品ID获取商品信息
    - 参数:
      - item_id: 商品ID(路径参数)
      - q: 查询关键词(查询参数,可选)
      - price: 价格筛选(查询参数,默认0.0)
    - 返回:包含商品信息的JSON
    """
    result = {"item_id": item_id}
    if q:
        result["query"] = q
    if price > 0:
        result["price"] = price
    return result

3.2 启动应用

(1) 开发模式启动

bash 复制代码
# 基础启动
uvicorn main:app --reload

# 指定主机和端口
uvicorn main:app --host 0.0.0.0 --port 8000 --reload

# 详细日志模式
uvicorn main:app --reload --log-level debug

参数说明:​

  • main:app:main.py文件中的app实例
  • --reload:开发模式,代码修改后自动重启
  • --host 0.0.0.0:允许外部访问
  • --port 8000:指定端口号

(2)访问应用​

3.3 代码解析

(1)核心概念

python 复制代码
# 导入FastAPI类
from fastapi import FastAPI

# 创建应用实例
app = FastAPI()

# 路由装饰器
@app.get("/")
def read_root():
    return {"Hello": "World"}

(2)路由装饰器

FastAPI 使用装饰器来定义路由:

python 复制代码
# GET请求
@app.get("/path")
def get_handler():
    pass

# POST请求
@app.post("/path")
def post_handler():
    pass

# PUT请求
@app.put("/path")
def put_handler():
    pass

# DELETE请求
@app.delete("/path")
def delete_handler():
    pass

4. 路由与参数详解

4.1 HTTP 方法详解

FastAPI 支持所有标准 HTTP 方法:

python 复制代码
from fastapi import FastAPI

app = FastAPI()

# GET - 获取资源
@app.get("/users")
def get_users():
    """获取所有用户"""
    return {"method": "GET", "action": "获取用户列表"}

# POST - 创建资源
@app.post("/users")
def create_user(user_data: dict):
    """创建新用户"""
    return {"method": "POST", "action": "创建用户", "data": user_data}

# PUT - 完整更新资源
@app.put("/users/{user_id}")
def update_user(user_id: int, user_data: dict):
    """更新用户信息(完整更新)"""
    return {"method": "PUT", "action": "更新用户", "user_id": user_id, "data": user_data}

# PATCH - 部分更新资源
@app.patch("/users/{user_id}")
def partial_update_user(user_id: int, user_data: dict):
    """部分更新用户信息"""
    return {"method": "PATCH", "action": "部分更新用户", "user_id": user_id, "data": user_data}

# DELETE - 删除资源
@app.delete("/users/{user_id}")
def delete_user(user_id: int):
    """删除用户"""
    return {"method": "DELETE", "action": "删除用户", "user_id": user_id}

4.2 参数类型详解​

(1) 路径参数(Path Parameters)​

路径参数是 URL 路径的一部分:

python 复制代码
from fastapi import FastAPI, HTTPException

app = FastAPI()

# 基础路径参数
@app.get("/users/{user_id}")
def get_user(user_id: int):
    """根据ID获取用户"""
    return {"user_id": user_id}

# 多个路径参数
@app.get("/users/{user_id}/items/{item_id}")
def get_user_item(user_id: int, item_id: str):
    """获取用户的特定商品"""
    return {"user_id": user_id, "item_id": item_id}

# 路径参数验证
@app.get("/items/{item_id}")
def get_item(
    item_id: int = Path(..., title="商品ID", description="商品的唯一标识符", ge=1, le=1000)
):
    """带验证的路径参数"""
    if item_id not in range(1, 1001):
        raise HTTPException(status_code=404, detail="商品不存在")
    return {"item_id": item_id}

(2)查询参数(Query Parameters)

查询参数是 URL 中?后面的键值对:

python 复制代码
from fastapi import FastAPI, Query
from typing import Union, List

app = FastAPI()

# 基础查询参数
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
    """分页获取商品列表"""
    return {"skip": skip, "limit": limit}

# 可选查询参数
@app.get("/search/")
def search(q: Union[str, None] = None):
    """搜索功能"""
    if q:
        return {"query": q, "results": ["结果1", "结果2"]}
    return {"message": "请提供搜索关键词"}

# 查询参数验证
@app.get("/filter/")
def filter_items(
    min_price: float = Query(0, ge=0, description="最低价格"),
    max_price: float = Query(1000, le=1000, description="最高价格"),
    categories: Union[List[str], None] = Query(None, description="商品分类")
):
    """带过滤条件的查询"""
    return {
        "min_price": min_price,
        "max_price": max_price,
        "categories": categories
    }

(3)请求体参数(Request Body)

请求体是客户端发送给服务器的数据:

python 复制代码
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Union

app = FastAPI()

# 定义数据模型
class Item(BaseModel):
    name: str
    price: float
    is_offer: Union[bool, None] = None

# 使用请求体
@app.post("/items/")
def create_item(item: Item):
    """创建商品"""
    item_dict = item.dict()
    if item.is_offer:
        item_dict.update({"discount": 0.1})
    return item_dict

# 混合参数类型
@app.put("/items/{item_id}")
def update_item(
    item_id: int,
    item: Item,
    q: Union[str, None] = None
):
    """更新商品(混合参数)"""
    result = {"item_id": item_id, **item.dict()}
    if q:
        result["query"] = q
    return result

4.3 参数验证与约束

FastAPI 提供强大的参数验证功能:

python 复制代码
from fastapi import FastAPI, Path, Query, Body
from typing import Union, List
from pydantic import BaseModel, Field

app = FastAPI()

# 路径参数验证
@app.get("/items/{item_id}")
def read_item(
    item_id: int = Path(
        ..., 
        title="商品ID",
        description="商品的唯一标识符",
        ge=1,          # 大于等于1
        le=1000,       # 小于等于1000
        example=42     # 示例值
    ),
    q: Union[str, None] = Query(
        None,
        title="查询关键词",
        description="用于搜索商品的关键词",
        min_length=3,  # 最小长度3
        max_length=50, # 最大长度50
        regex="^[a-zA-Z0-9 ]*$"  # 正则表达式验证
    )
):
    return {"item_id": item_id, "q": q}

# 请求体验证
class User(BaseModel):
    username: str = Field(
        ...,
        title="用户名",
        description="用户的登录名",
        min_length=3,
        max_length=20,
        example="johndoe"
    )
    email: str = Field(
        ...,
        title="邮箱",
        description="用户的邮箱地址",
        regex=r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
        example="john@example.com"
    )
    age: int = Field(
        None,
        title="年龄",
        description="用户年龄",
        ge=18,
        le=120
    )

@app.post("/users/")
def create_user(user: User = Body(..., description="用户信息")):
    return user

5. 交互式 API 文档

5.1 自动生成的文档​

FastAPI 自动生成两种交互式 API 文档:​

(1) Swagger UI(推荐)

访问地址:http://127.0.0.1:8000/docs

功能特点:​

  • 交互式界面,支持直接测试 API
  • 自动生成请求参数表单
  • 显示响应示例和状态码
  • 支持认证和授权
  • 可导出 API 文档

(2)ReDoc

访问地址:http://127.0.0.1:8000/redoc

功能特点:​

  • 更简洁的文档风格
  • 更好的排版和可读性
  • 支持 Markdown 格式的描述
  • 适合生产环境展示

5.2 文档配置与定制

(1)应用元数据配置

python 复制代码
from fastapi import FastAPI

app = FastAPI(
    title="电子商务API",
    description="""
    这是一个完整的电子商务API服务,提供以下功能:
    
    - 用户管理:注册、登录、个人信息管理
    - 商品管理:商品CRUD、分类、搜索
    - 订单管理:创建订单、支付、物流跟踪
    - 购物车:添加商品、修改数量、结算
    
    **技术栈:** FastAPI + Pydantic + SQLAlchemy
    """,
    version="2.0.0",
    terms_of_service="http://example.com/terms/",
    contact={
        "name": "API支持团队",
        "url": "http://example.com/contact/",
        "email": "support@example.com",
    },
    license_info={
        "name": "MIT License",
        "url": "https://opensource.org/licenses/MIT",
    },
)

@app.get("/")
def read_root():
    return {"message": "欢迎使用电子商务API"}

(2)接口文档配置

python 复制代码
from fastapi import FastAPI, Query
from typing import Union

app = FastAPI()

@app.get(
    "/items/",
    summary="获取商品列表",
    description="""
    获取商品列表,支持分页和过滤:
    
    - **分页**:通过skip和limit参数控制
    - **过滤**:通过category和min_price参数过滤
    - **排序**:通过sort_by参数指定排序字段
    
    返回商品的基本信息,包括ID、名称、价格等。
    """,
    response_description="成功返回商品列表",
    tags=["商品管理"],
    deprecated=False  # 是否弃用
)
def read_items(
    skip: int = Query(0, description="跳过的商品数量", ge=0),
    limit: int = Query(10, description="获取的商品数量", ge=1, le=100),
    category: Union[str, None] = Query(None, description="商品分类"),
    min_price: Union[float, None] = Query(None, description="最低价格", ge=0)
):
    """
    获取商品列表:
    
    - **skip**: 跳过的商品数量(默认0)
    - **limit**: 获取的商品数量(默认10,最大100)
    - **category**: 商品分类(可选)
    - **min_price**: 最低价格(可选)
    
    返回包含商品信息的列表。
    """
    return {"skip": skip, "limit": limit, "category": category, "min_price": min_price}

5.3 文档分组与标签

使用tags参数对 API 进行分组:

python 复制代码
from fastapi import FastAPI

app = FastAPI()

# 用户管理相关接口
@app.get("/users/", tags=["用户管理"], summary="获取用户列表")
def get_users():
    """获取所有用户的基本信息"""
    return {"message": "用户列表"}

@app.post("/users/", tags=["用户管理"], summary="创建新用户")
def create_user(user_data: dict):
    """创建新用户,需要提供用户名、邮箱和密码"""
    return {"message": "用户创建成功", "data": user_data}

@app.get("/users/{user_id}", tags=["用户管理"], summary="获取用户详情")
def get_user(user_id: int):
    """根据用户ID获取用户的详细信息"""
    return {"user_id": user_id, "message": "用户详情"}

# 商品管理相关接口
@app.get("/items/", tags=["商品管理"], summary="获取商品列表")
def get_items():
    """获取所有商品的基本信息"""
    return {"message": "商品列表"}

@app.post("/items/", tags=["商品管理"], summary="创建新商品")
def create_item(item_data: dict):
    """创建新商品,需要提供商品名称、价格、描述等信息"""
    return {"message": "商品创建成功", "data": item_data}

# 订单管理相关接口
@app.get("/orders/", tags=["订单管理"], summary="获取订单列表")
def get_orders():
    """获取所有订单的基本信息"""
    return {"message": "订单列表"}

@app.post("/orders/", tags=["订单管理"], summary="创建新订单")
def create_order(order_data: dict):
    """创建新订单,需要提供商品ID、数量、收货地址等信息"""
    return {"message": "订单创建成功", "data": order_data}

5.4 响应模型文档

python 复制代码
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List, Union

app = FastAPI()

# 定义响应模型
class Item(BaseModel):
    """商品信息模型"""
    id: int
    name: str
    price: float
    description: Union[str, None] = None

class ItemListResponse(BaseModel):
    """商品列表响应模型"""
    items: List[Item]
    total: int
    skip: int
    limit: int

@app.get("/items/", response_model=ItemListResponse, summary="获取商品列表")
def read_items(skip: int = 0, limit: int = 10):
    """
    获取商品列表:
    
    - 返回商品的详细信息
    - 包含分页信息
    - 支持大量数据的高效返回
    """
    # 模拟数据库查询
    mock_items = [
        {"id": 1, "name": "商品1", "price": 99.99, "description": "这是商品1的描述"},
        {"id": 2, "name": "商品2", "price": 199.99},
    ]
    
    return {
        "items": mock_items,
        "total": len(mock_items),
        "skip": skip,
        "limit": limit
    }

FastAPI 的学习是一个循序渐进的过程,建议你在实际项目中不断实践和探索。在下一篇文章中,我们将深入学习 FastAPI 的进阶特性和实战应用

相关推荐
<但凡.4 小时前
Linux修炼:基础IO(二)
linux·运维·服务器·1024程序员节
2301_803554524 小时前
std::unique_lockstd::mutex lock(mtx) 深度详解
1024程序员节
黑翼杰克斯4 小时前
关于buildroot文件系统中rootfs的内容,该怎么增删(瑞芯微rv1126b)
linux·音视频·1024程序员节
wodongx1234 小时前
从一开始部署Android项目Sonarqube的自动化扫码+通知+增量扫描功能(Win环境、Docker,基于Jenkins)
运维·docker·jenkins·1024程序员节
豆沙沙包?4 小时前
2025年--Lc216- 400. 第 N 位数字(找规律)-Java版
1024程序员节
shepherd1264 小时前
破局延时任务(上):为什么选择Spring Boot + DelayQueue来自研分布式延时队列组件?
java·spring boot·后端·1024程序员节
Lethehong4 小时前
以LIS为突破口的全栈信创实践——浙江省人民医院多院区多活架构建设样本
lis·1024程序员节·kingbase·kes·kfs
言德斐4 小时前
Python Web框架深度对比:Django vs Flask vs FastAPI(含优缺点与选型策略)
前端·python·django
通往曙光的路上4 小时前
day18_菜单查询 合并servlet
1024程序员节