第一章. 路由(Routing)

是什么

是用一个装饰器(@app.get() / @app.post() 等)来装饰处理函数,从而建立 URL 地址与处理函数之间的映射关系

通俗来说就是当用户访问某个网址时,FastAPI 通过路由执行对应的函数。


作用

在 Web / AI 服务中,所有外部请求都会通过 URL 进入系统,例如:

上传图片进行检测、请求模型预测结果、查询设备状态、获取历史数据等

而路由的作用就是:

接收请求→找到对应函数→执行业务逻辑→返回结果

如果没有路由:所有请求都挤在一个函数里,代码会非常混乱,系统也无法扩展

可以把 FastAPI 想象成一个 快递分拣中心

URL = 快递单号;路由 = 分拣规则;处理函数 = 对应工作人员

流程是:请求进来 → 查看URL → 匹配路由 → 调用对应函数 → 返回结果

比如访问:

http://127.0.0.1:8000/predict

FastAPI 会自动找到:

@app.post("/predict")

def predict(): ...

然后执行 predict() 这个函数。


基本用法示例

① 最简单的路由

from fastapi import FastAPI

app = FastAPI()

@app.get("/")

def home():

    return {"msg": "hello world"}

含义是:当访问 ”/“的时候,使用 GET 请求,执行 home() 函数,并返回结果


② 多个路由对应不同功能

@app.get("/status") 
def status():
    return {"status": "running"} 

@app.post("/predict") 
def predict(data: dict): 
    return {"result": 123} 

@app.get("/history") 
def history(): 
    return {"records": []}

此时,每个功能互不干扰,代码清晰:

URL 功能
/status 查看系统状态
/predict 模型推理
/history 查询历史记录

常见请求类型

FastAPI 通过不同装饰器区分“请求方式”:

装饰器 含义 常见用途
@app.get 获取数据 查询状态/结果
@app.post 提交数据 模型推理/上传图片
@app.put 更新数据 更新配置
@app.delete 删除数据 删除记录

第二章 FastAPI 参数(Parameters)

2.1 参数到底是干什么的?

一句话总结:参数 = 客户端传给服务器的数据。服务器不可能“凭空处理业务”,必须依赖用户提供的数据。比如:

场景 需要什么数据
查询用户 user_id
分页列表 page + size
AI预测 图片/数组/JSON
提交表单 username + password

这些数据,统统叫:参数(Parameters)

我们可以把 API 想成办事大厅:

元素 类比
路由 办事窗口
参数 你递交的材料

没有材料(参数),工作人员(函数)啥也干不了。


2.2 FastAPI 为什么要分三种参数?

因为不同数据,传输位置应该不同。如果你把所有数据都塞进 URL:

/predict?img=xxxxx超长xxxxx

因为URL 的长度有限,可能直接崩溃了。

所以 HTTP 协议把数据分为:

位置 特点
URL路径 标识资源
URL查询串 小数据筛选
HTTP Body 大数据/复杂数据

于是 FastAPI 顺势设计了:Path、Query、Body三种参数类型。


2.3 三种参数怎么选?

实战中需要根据场景选择参数,具体如下:

场景 用哪种 示例
获取某个具体对象 Path /user/100
分页/筛选/搜索 Query ?page=1
提交JSON/数组/文件 Body POST数据
传图片/数据/numpy Body POST

总结一下各自的用途:查“谁” → Path;查“条件” → Query;传“大东西” → Body,下面分别详细介绍一下三个参数怎么用


2.4 路径参数(Path)


 是什么?

它是写在 URL 路径中的变量。作用只有一个:唯一定位资源。举个例子:

127.0.0.1:8000/room/305

305 就是房间号。是精确定位房间305这个资源。


典型场景

✔ 查询某个用户 ✔ 查询某条记录 ✔ 下载某张图片 ✔ 删除某条数据


基础写法

from fastapi import FastAPI, Path, Query

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

# 定义 GET 请求接口 /user/{user_id}
@app.get("/user/{user_id}")  
# 说明:
# - URL 中使用 {user_id} 表示这是一个路径参数(path parameter)
# - FastAPI 会自动把 URL 中的值传递给下面的 user_id 参数
# - {} 中的名字要和函数参数名一致
def get_user(user_id: int):  
    """
    获取指定用户信息接口示例

    参数说明:
    - user_id: 路径参数(path),类型 int
      * FastAPI 会自动将 URL 中的字符串转换成 int
      * 如果传入非整数,会返回 422 错误(Unprocessable Entity)

    返回:
    - JSON 格式包含 user_id
    """
    # 返回请求的 user_id,用于示例展示
    return {"user_id": user_id}

执行结果(输入2):


Path()的使用(主要是对参数做限制与描述)

from fastapi import Path 
@app.get("/user/{user_id}") 
def get_user( user_id: int = Path(..., ge=1, description="用户ID") ): 
    return {"user_id": user_id}

输出结果:

{
  "user_id": 2
}

ID限制了必须≥1,否则就会报错:下面是Path()内常用的参数:

参数 类型 作用 示例 说明
... 必填 强制必传 Path(...) Path永远必填
gt 数值 > gt=0 大于
ge 数值 ge=1 大于等于
lt 数值 < lt=100 小于
le 数值 le=99 小于等于
description str 文档说明 description="用户ID" Swagger显示
example any 示例值 example=10 文档示例

2.5 查询参数(Query)

是什么?

写在URL的 ? 后面的小型参数,通常用于过滤或查询条件。

/logs?page=1&size=20

典型场景

✔ 分页 ✔ 时间筛选 ✔ 搜索关键词 ✔ 排序方式


基础写法

from fastapi import FastAPI, Path, Query

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

# 定义 GET 请求接口 /logs
@app.get("/logs")
def get_logs(
    page: int = 1,  # 查询参数 page,类型 int,默认值 1 → 可选参数,不传使用默认值
    size: int = 10  # 查询参数 size,类型 int,默认值 10 → 可选参数,不传使用默认值
):
    """
    获取日志列表的接口示例

    参数说明:
    - page: 页码(默认 1,可选)
    - size: 每页显示条数(默认 10,可选)

    返回:
    - JSON 格式包含 page 和 size
    """
    # 返回请求参数,用于示例展示
    return {"page": page, "size": size}

结果url输出

结果输出:

推荐写法(带校验)

from fastapi import Query 
@app.get("/logs") 
def get_logs( page: int = Query(1, ge=1), size: int = Query(10, le=100) ): 
    return {"page": page, "size": size}

Query()的使用(跟Path()类似,主要是对查询参数做限制与描述,与Path()不同的是Query()支持默认值)

参数 类型 作用 示例 说明
默认值 任意 可选参数 Query(1) 不传使用默认
... 必填 强制必传 Query(...) 必须提供
gt/ge/lt/le 数值范围 同Path ge=1 数值限制
min_length 最小长度 min_length=3 字符串专用
max_length 最大长度 max_length=10 字符串专用
description 文档说明 description="页码" docs显示
example 示例值 example=1 示例展示

优点: ✔ 可选参数 ✔ 默认值友好 ✔ 非常适合 GET 请求

注意不要通过查询参数传:图片、numpy数组、长文本。因为URL 长度有限(浏览器限制)


2.6 请求体参数(Body)

是什么?

数据放在 HTTP Body 中发送。这是传输复杂数据的正确方式。需要传包括但不限于下面任意一个数据时,直接用 Body:✔ JSON  ✔ 字典  ✔ 数组  ✔ 文件  ✔ AI模型输入  ✔ 大数据。

HTTP Body基本概念

在讲请求体参数之前,我们来系统讲清楚 HTTP Body 是什么,它的概念、作用以及在 FastAPI 里的对应用法。

HTTP Body(请求体)是指:在 HTTP 请求中,URL(路径 + 查询参数)之外,附加的原始数据部分。它通常用于 POST / PUT / PATCH 等需要传递数据的请求。


HTTP 的请求结构如下所示:

POST /users HTTP/1.1

Host: example.com

Content-Type: application/json

Content-Length: 48

{

"username": "tom",

"age": 18

}

  • 请求行:POST /users

  • 请求头:Host, Content-Type, Content-Length …

  • 请求体(Body):{ "username": "tom", "age": 18 }


HTTP Body 的作用

作用 说明
传递数据 URL和Query参数长度有限,Body可以传大量数据
支持复杂类型 JSON、XML、表单、二进制文件等
RESTful POST/PUT 常用 用于创建或修改资源

Body 在 FastAPI 中的使用

FastAPI 使用 Pydantic 模型Body() 来解析请求体。


示例 1:使用 Pydantic 模型接收 JSON Body(适用于字段更多、验证规则更复杂的数据)

from fastapi import FastAPI
from pydantic import BaseModel

# ===============================
# 1.创建 FastAPI 应用实例
# ===============================
# FastAPI 应用对象,所有路由和中间件都注册在这个 app 上
app = FastAPI()


# ===============================
# 2.定义 Pydantic 数据模型
# ===============================
# BaseModel 是 Pydantic 提供的基类,用于定义请求体的数据结构
# Pydantic 会自动做类型检查、必填校验、默认值支持和文档生成
class User(BaseModel):
    username: str  # 用户名,必须是字符串类型
    age: int       # 年龄,必须是整数类型


# ===============================
# 3.定义 POST 接口,接收 JSON Body
# ===============================
@app.post("/users")  # 路由:POST /users
def create_user(user: User):  # 参数 user 从请求体 JSON 自动解析成 User 实例
    """
    创建用户接口示例

    参数说明:
    - user: 请求体 (Body) JSON 对象,字段对应 User 模型
        * username: str
        * age: int

    返回:
    - JSON 格式,包含创建提示信息
    """
    
    # 访问 user 对象的属性
    # FastAPI + Pydantic 会自动做类型校验:
    # 如果 JSON 中缺少 username 或 age,或者类型错误,会返回 422 错误
    # 例如:{"username": "tom", "age": "abc"} → 422
    return {"msg": f"创建用户 {user.username}, 年龄 {user.age}"}

输出结果,可以看到数据没有显示在URL里,而是显示在了请求体里-d 后面


  • FastAPI 自动把 JSON → User 实例

  • 类型检查、必填校验、文档自动生成都生效


示例 2:使用 Body() 指定参数来源(对于简单表单/登录接口,直接使用 Body() 指定参数即可)

from fastapi import FastAPI, Body

app = FastAPI()


# ===============================
# POST 接口示例:登录
# ===============================
@app.post("/login")  # 路由:POST /login
def login(
        username: str = Body(..., description="用户名"),  # 从请求体中获取 username 参数
        password: str = Body(..., description="密码")  # 从请求体中获取 password 参数
):
    """
    用户登录接口示例

    参数说明:
    - username: str
        * 来自 HTTP Body
        * 必填(... 表示必填)
        * Swagger 文档中显示描述 "用户名"
    - password: str
        * 来自 HTTP Body
        * 必填
        * Swagger 文档中显示描述 "密码"

    返回:
    - JSON 格式,包含用户信息或登录提示
    """

    # ===============================
    # 访问 Body 参数
    # ===============================
    # FastAPI 自动从 HTTP Body 中提取字段
    # Body(...) 表示参数必填,如果前端没传,会返回 422 错误
    # 例如:
    # 请求体:
    # {
    #   "username": "tom",
    #   "password": "123456"
    # }
    # FastAPI 自动将 JSON 中 username/password 解析为函数参数

    # 这里仅返回 username,示例演示如何访问 Body 参数
    return {"user": username}

输出结果:


HTTP Body 的格式类型

常见 Content-Type:

类型 说明
application/json JSON 数据(最常用)
application/x-www-form-urlencoded 表单键值对
multipart/form-data 文件上传 + 表单
text/plain 纯文本
application/xml XML 数据

FastAPI 默认解析 JSON,上传文件用 File(),表单用 Form()

Field()的使用(跟Path()类似,主要是对请求体参数做限制与描述,与Path()不同的是Field()是在BaseModel内使用)

推荐写法:

from fastapi import FastAPI          # FastAPI 框架
from pydantic import BaseModel, Field  # 数据模型 + 字段校验工具


# ===============================
# 创建 FastAPI 应用对象
# ===============================

app = FastAPI()


# ===============================
# 定义请求体数据模型(Body Model)
# ===============================
# BaseModel:Pydantic 提供的数据校验基类
# 所有请求体 JSON 都会自动转换成该对象
# 同时自动做:类型转换 + 数据校验 + 文档生成

class Book(BaseModel):

    # ... 代表必填字段(必须传)
    # min_length / max_length:字符串长度限制
    # description:Swagger 文档说明
    name: str = Field(
        ...,                      # 必填
        min_length=1,             # 最小长度
        max_length=50,            # 最大长度
        description="书名"
    )

    # gt:greater than(必须 > 0)
    # float:自动把前端字符串/整数转换成浮点数
    price: float = Field(
        ...,                      # 必填
        gt=0,                     # 价格必须 > 0
        description="图书价格"
    )

# 请求方式:POST
# 路由地址:/books
# 请求体:JSON(自动映射为 Book 对象)

@app.post("/books")
def create_book(book: Book):
    """
    新增图书接口

    参数:
        book: Book
        - 来自 HTTP Body(JSON)
        - 自动解析为 Book 对象
        - 自动做字段校验

    示例请求:
    {
        "name": "FastAPI实战",
        "price": 88.5
    }
    """

    # 可以直接使用对象属性
    return {
        "msg": "创建成功",
        "name": book.name,
        "price": book.price
    }

Field 常用参数表

参数 含义 示例
default 默认值 Field(0)
... 必填 Field(...)
title 标题 title="价格"
description 描述 description="商品价格"
example 示例值 example=99.9
min_length 最小长度 min_length=3
max_length 最大长度 max_length=20
regex 正则限制 regex="^[0-9]+$"
gt > gt=0
ge ge=0
lt < lt=100
le le=100
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐