路径操作 #

路径操作装饰器 #

基本语法 #

python
@app.get('/path')
def handler():
    return {'message': 'Hello'}

支持的 HTTP 方法 #

text
┌─────────────────────────────────────────────────────────────┐
│                    HTTP 方法装饰器                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   @app.get()       读取资源                                  │
│   @app.post()      创建资源                                  │
│   @app.put()       更新资源(完整替换)                       │
│   @app.patch()     更新资源(部分更新)                       │
│   @app.delete()    删除资源                                  │
│   @app.options()   获取支持的 HTTP 方法                       │
│   @app.head()      获取响应头                                │
│   @app.trace()     跟踪路径                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

装饰器参数 #

python
@app.get(
    '/items/{item_id}',
    response_model=Item,
    status_code=200,
    tags=['items'],
    summary='Get an item',
    description='Get a specific item by ID',
    response_description='The requested item',
    deprecated=False,
)
def read_item(item_id: int):
    return {'item_id': item_id}

路由顺序 #

python
# 正确:具体路径在前
@app.get('/users/me')
def read_users_me():
    return {'user_id': 'current_user'}

@app.get('/users/{user_id}')
def read_user(user_id: str):
    return {'user_id': user_id}

# 错误:通配路径在前会匹配所有
# @app.get('/users/{user_id}')  # 会匹配 /users/me
# def read_user(user_id: str):
#     return {'user_id': user_id}

路径参数 #

基本使用 #

python
@app.get('/items/{item_id}')
def read_item(item_id: int):
    return {'item_id': item_id}

类型转换 #

python
@app.get('/items/{item_id}')
def read_item(item_id: int):      # 自动转换为整数
    return {'item_id': item_id}

@app.get('/users/{user_id}')
def read_user(user_id: str):      # 字符串类型
    return {'user_id': user_id}

@app.get('/items/{item_id}/price')
def read_item_price(item_id: int, price: float):  # 浮点数
    return {'item_id': item_id, 'price': price}

@app.get('/items/{item_id}/active')
def read_item_active(item_id: int, active: bool):  # 布尔值
    return {'item_id': item_id, 'active': active}

路径参数验证 #

python
from fastapi import Path

@app.get('/items/{item_id}')
def read_item(
    item_id: int = Path(
        ...,
        title='Item ID',
        description='The ID of the item to retrieve',
        ge=1,
        le=1000
    )
):
    return {'item_id': item_id}

验证约束 #

text
┌─────────────────────────────────────────────────────────────┐
│                    路径参数验证约束                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   数值类型:                                                 │
│   gt   大于          ge   大于等于                          │
│   lt   小于          le   小于等于                          │
│                                                             │
│   字符串类型:                                               │
│   min_length   最小长度                                     │
│   max_length   最大长度                                     │
│   regex        正则表达式                                   │
│                                                             │
│   示例:                                                    │
│   item_id: int = Path(..., ge=1, le=100)                    │
│   name: str = Path(..., min_length=2, max_length=50)        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

枚举路径参数 #

python
from enum import Enum

class ModelName(str, Enum):
    alexnet = 'alexnet'
    resnet = 'resnet'
    lenet = 'lenet'

@app.get('/models/{model_name}')
def get_model(model_name: ModelName):
    return {'model_name': model_name, 'value': model_name.value}

包含路径的参数 #

python
@app.get('/files/{file_path:path}')
def read_file(file_path: str):
    return {'file_path': file_path}

访问 /files/home/johndoe/myfile.txt

json
{"file_path": "home/johndoe/myfile.txt"}

查询参数 #

基本使用 #

python
@app.get('/items/')
def read_items(skip: int = 0, limit: int = 10):
    return {'skip': skip, 'limit': limit}

访问 /items/?skip=20&limit=30

json
{"skip": 20, "limit": 30}

必需查询参数 #

python
@app.get('/items/')
def read_items(skip: int, limit: int):  # 没有默认值,必需
    return {'skip': skip, 'limit': limit}

可选查询参数 #

python
from typing import Optional

@app.get('/items/{item_id}')
def read_item(item_id: str, q: Optional[str] = None):
    if q:
        return {'item_id': item_id, 'q': q}
    return {'item_id': item_id}

查询参数验证 #

python
from fastapi import Query

@app.get('/items/')
def read_items(
    q: Optional[str] = Query(
        None,
        min_length=3,
        max_length=50,
        regex='^[a-zA-Z]+$'
    )
):
    return {'q': q}

必需查询参数验证 #

python
@app.get('/items/')
def read_items(
    q: str = Query(
        ...,
        min_length=3,
        description='Search query string'
    )
):
    return {'q': q}

默认值查询参数 #

python
@app.get('/items/')
def read_items(
    q: str = Query('default', min_length=3)
):
    return {'q': q}

查询参数列表 #

python
@app.get('/items/')
def read_items(q: list[str] = Query([])):
    return {'q': q}

访问 /items/?q=foo&q=bar

json
{"q": ["foo", "bar"]}

查询参数别名 #

python
@app.get('/items/')
def read_items(
    q: Optional[str] = Query(None, alias='item-query')
):
    return {'q': q}

访问 /items/?item-query=foo

弃用参数 #

python
@app.get('/items/')
def read_items(
    q: Optional[str] = Query(
        None,
        alias='item-query',
        deprecated=True
    )
):
    return {'q': q}

参数组合 #

路径参数 + 查询参数 #

python
@app.get('/users/{user_id}/items/{item_id}')
def read_user_item(
    user_id: int,
    item_id: str,
    q: Optional[str] = None,
    short: bool = False
):
    item = {'item_id': item_id, 'owner_id': user_id}
    if q:
        item.update({'q': q})
    if not short:
        item.update({'description': 'Long description'})
    return item

多种参数混合 #

python
from fastapi import FastAPI, Path, Query

@app.get('/items/{item_id}')
def read_item(
    item_id: int = Path(..., title='Item ID', ge=1),
    q: Optional[str] = Query(None, min_length=3),
    size: float = Query(1.0, gt=0, lt=10.5)
):
    return {'item_id': item_id, 'q': q, 'size': size}

请求体 #

定义请求体模型 #

python
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

@app.post('/items/')
def create_item(item: Item):
    return item

请求体 + 路径参数 + 查询参数 #

python
@app.put('/items/{item_id}')
def update_item(
    item_id: int,
    item: Item,
    q: Optional[str] = None
):
    result = {'item_id': item_id, **item.model_dump()}
    if q:
        result.update({'q': q})
    return result

多个请求体参数 #

python
class Item(BaseModel):
    name: str
    price: float

class User(BaseModel):
    username: str
    full_name: Optional[str] = None

@app.put('/items/{item_id}')
def update_item(item_id: int, item: Item, user: User):
    return {'item_id': item_id, 'item': item, 'user': user}

请求体格式:

json
{
    "item": {
        "name": "Foo",
        "price": 45.2
    },
    "user": {
        "username": "john",
        "full_name": "John Doe"
    }
}

单个值请求体 #

python
from fastapi import Body

@app.put('/items/{item_id}')
def update_item(
    item_id: int,
    item: Item,
    importance: int = Body(...)
):
    return {'item_id': item_id, 'item': item, 'importance': importance}

嵌入单个请求体 #

python
@app.put('/items/{item_id}')
def update_item(item_id: int, item: Item = Body(..., embed=True)):
    return {'item_id': item_id, 'item': item}

请求体格式:

json
{
    "item": {
        "name": "Foo",
        "price": 45.2
    }
}

表单数据 #

接收表单数据 #

python
from fastapi import FastAPI, Form

app = FastAPI()

@app.post('/login/')
def login(username: str = Form(...), password: str = Form(...)):
    return {'username': username}

文件上传 #

python
from fastapi import FastAPI, File, UploadFile

app = FastAPI()

@app.post('/files/')
def create_file(file: bytes = File(...)):
    return {'file_size': len(file)}

@app.post('/uploadfile/')
def create_upload_file(file: UploadFile):
    return {'filename': file.filename}

多文件上传 #

python
@app.post('/files/')
def create_files(files: list[bytes] = File(...)):
    return {'file_sizes': [len(file) for file in files]}

@app.post('/uploadfiles/')
def create_upload_files(files: list[UploadFile]):
    return {'filenames': [file.filename for file in files]}

请求头 #

python
from fastapi import FastAPI, Header

app = FastAPI()

@app.get('/items/')
def read_items(user_agent: Optional[str] = Header(None)):
    return {'User-Agent': user_agent}

带下划线的请求头 #

python
@app.get('/items/')
def read_items(
    x_token: Optional[str] = Header(None, convert_underscores=True)
):
    return {'X-Token': x_token}
python
from fastapi import FastAPI, Cookie

app = FastAPI()

@app.get('/items/')
def read_items(ads_id: Optional[str] = Cookie(None)):
    return {'ads_id': ads_id}

响应状态码 #

设置状态码 #

python
from fastapi import FastAPI, status

app = FastAPI()

@app.post('/items/', status_code=201)
def create_item(name: str):
    return {'name': name}

@app.delete('/items/{item_id}', status_code=status.HTTP_204_NO_CONTENT)
def delete_item(item_id: int):
    return None

常用状态码 #

text
┌─────────────────────────────────────────────────────────────┐
│                    HTTP 状态码                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   2xx 成功                                                  │
│   200 OK              请求成功                              │
│   201 Created         资源创建成功                          │
│   204 No Content      成功但无返回内容                       │
│                                                             │
│   4xx 客户端错误                                             │
│   400 Bad Request     请求格式错误                          │
│   401 Unauthorized    未认证                                │
│   403 Forbidden       无权限                                │
│   404 Not Found       资源不存在                            │
│   422 Unprocessable   验证失败                              │
│                                                             │
│   5xx 服务器错误                                             │
│   500 Internal Error  服务器内部错误                         │
│   503 Service Unavailable 服务不可用                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

下一步 #

现在你已经掌握了路径操作,接下来学习 请求体,深入了解 FastAPI 的数据验证机制!

最后更新:2026-03-29