← Назад к вопросам

Как указать тип HTTP запроса в FastAPI?

2.0 Middle🔥 221 комментариев
#FastAPI и Flask#REST API и HTTP

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

HTTP методы в FastAPI

FastAPI предоставляет декораторы для каждого HTTP метода, которые связывают URL путь с функцией-обработчиком. Вот все основные способы:

Основные HTTP методы

1. GET — получить данные

Используется для: чтение данных, без изменения состояния

from fastapi import FastAPI

app = FastAPI()

# Простой GET
@app.get("/items")
async def get_items():
    return [{"id": 1, "name": "Item 1"}]

# GET с параметром пути
@app.get("/items/{item_id}")
async def get_item(item_id: int):
    return {"id": item_id, "name": f"Item {item_id}"}

# GET с query параметрами
@app.get("/items/")
async def list_items(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}

2. POST — создать данные

Используется для: создание новых ресурсов

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float
    description: str = None

@app.post("/items")
async def create_item(item: Item):
    # item будет распарсен из JSON body
    return {
        "message": "Item created",
        "item": item
    }

# Использование
# POST /items
# Content-Type: application/json
# {"name": "Laptop", "price": 999.99, "description": "Gaming laptop"}

3. PUT — обновить весь ресурс

Используется для: полное обновление ресурса

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    return {
        "message": f"Item {item_id} updated",
        "item_id": item_id,
        "item": item
    }

# Использование
# PUT /items/1
# {"name": "Updated", "price": 1500.0, "description": "New description"}

4. PATCH — частичное обновление

Используется для: обновление некоторых полей ресурса

from typing import Optional

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

@app.patch("/items/{item_id}")
async def partial_update_item(item_id: int, item_update: ItemUpdate):
    # Обновляем только переданные поля
    updated_fields = item_update.dict(exclude_unset=True)
    return {
        "message": f"Item {item_id} partially updated",
        "updated_fields": updated_fields
    }

# Использование
# PATCH /items/1
# {"price": 1200.0}  <- только цена

5. DELETE — удалить ресурс

Используется для: удаление ресурсов

@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
    return {"message": f"Item {item_id} deleted"}

# Использование
# DELETE /items/1

Полный пример: REST API для управления товарами

from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime

app = FastAPI()

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

class ItemInDB(Item):
    id: int
    created_at: datetime

# Имитация БД
fake_db = {
    1: {
        "id": 1,
        "name": "Laptop",
        "price": 999.99,
        "description": "Gaming laptop",
        "created_at": datetime.now()
    }
}

# GET — получить все товары
@app.get("/items", response_model=List[ItemInDB])
async def list_items(skip: int = 0, limit: int = 10):
    items = list(fake_db.values())
    return items[skip:skip + limit]

# GET — получить конкретный товар
@app.get("/items/{item_id}", response_model=ItemInDB)
async def get_item(item_id: int):
    if item_id not in fake_db:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Item {item_id} not found"
        )
    return fake_db[item_id]

# POST — создать товар
@app.post("/items", response_model=ItemInDB, status_code=status.HTTP_201_CREATED)
async def create_item(item: Item):
    new_id = max(fake_db.keys()) + 1 if fake_db else 1
    new_item = {
        "id": new_id,
        "created_at": datetime.now(),
        **item.dict()
    }
    fake_db[new_id] = new_item
    return new_item

# PUT — обновить весь товар
@app.put("/items/{item_id}", response_model=ItemInDB)
async def update_item(item_id: int, item: Item):
    if item_id not in fake_db:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Item {item_id} not found"
        )
    
    updated_item = {
        "id": item_id,
        "created_at": fake_db[item_id]["created_at"],
        **item.dict()
    }
    fake_db[item_id] = updated_item
    return updated_item

# PATCH — частично обновить товар
@app.patch("/items/{item_id}", response_model=ItemInDB)
async def partial_update_item(
    item_id: int,
    item_update: ItemUpdate
):
    if item_id not in fake_db:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Item {item_id} not found"
        )
    
    current_item = fake_db[item_id]
    updated = current_item.copy()
    
    # Обновляем только переданные поля
    for field, value in item_update.dict(exclude_unset=True).items():
        updated[field] = value
    
    fake_db[item_id] = updated
    return updated

# DELETE — удалить товар
@app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_item(item_id: int):
    if item_id not in fake_db:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Item {item_id} not found"
        )
    
    del fake_db[item_id]
    return None  # 204 No Content

Несколько методов на одном пути

from fastapi import FastAPI

app = FastAPI()

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

# Можно определить разные методы для одного пути
@app.get("/items/{item_id}")
async def get_item(item_id: int):
    return {"id": item_id}

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    return {"id": item_id, **item.dict()}

@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
    return {"message": "deleted"}

# FastAPI автоматически создаст документацию для всех методов

Несколько HTTP методов в одном декораторе

@app.api_route("/items/{item_id}", methods=["GET", "PUT"])
async def get_or_update_item(
    item_id: int,
    item: Optional[Item] = None
):
    if request.method == "GET":
        return {"id": item_id}
    elif request.method == "PUT":
        return {"id": item_id, **item.dict()}

# Примечание: лучше не использовать этот подход,
# лучше определить отдельные функции для каждого метода

HEAD и OPTIONS

# HEAD — как GET, но без тела ответа
@app.head("/items/{item_id}")
async def head_item(item_id: int):
    return {}

# OPTIONS — информация о доступных методах
# FastAPI обрабатывает автоматически

Status коды

from fastapi import status
from fastapi.responses import JSONResponse

# 200 OK — по умолчанию для GET
@app.get("/items")
async def list_items():
    return [{"id": 1}]

# 201 Created — для POST
@app.post("/items", status_code=status.HTTP_201_CREATED)
async def create_item(item: Item):
    return item

# 204 No Content — для DELETE
@app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_item(item_id: int):
    return None

# 400 Bad Request — ошибка в запросе
@app.post("/items")
async def create_item(item: Item):
    if item.price < 0:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Price cannot be negative"
        )
    return item

# 401 Unauthorized — требуется аутентификация
@app.get("/admin", status_code=status.HTTP_401_UNAUTHORIZED)
async def admin_panel():
    raise HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Authentication required"
    )

# 403 Forbidden — недостаточно прав
@app.delete("/items/{item_id}")
async def delete_item(item_id: int, user: User = Depends(get_current_user)):
    if user.role != "admin":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Only admins can delete items"
        )
    return {"message": "deleted"}

# 404 Not Found
@app.get("/items/{item_id}")
async def get_item(item_id: int):
    item = db.get_item(item_id)
    if not item:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Item not found"
        )
    return item

Параметры запроса

from fastapi import Query, Path, Body, Header
from typing import Optional

# Path параметры
@app.get("/items/{item_id}")
async def get_item(
    item_id: int = Path(..., gt=0, description="Item ID должен быть > 0")
):
    return {"id": item_id}

# Query параметры
@app.get("/items")
async def list_items(
    skip: int = Query(0, ge=0),
    limit: int = Query(10, ge=1, le=100)
):
    return {"skip": skip, "limit": limit}

# Body параметры
class Item(BaseModel):
    name: str
    price: float

@app.post("/items")
async def create_item(
    item: Item = Body(..., embed=True)
):
    return item

# Headers
@app.get("/items")
async def get_items(
    x_token: str = Header(...)
):
    return {"token": x_token}

Таблица HTTP методов

МетодИспользованиеПримерStatus код
GETПолучить данныеGET /items/1200
POSTСоздать ресурсPOST /items201
PUTПолное обновлениеPUT /items/1200
PATCHЧастичное обновлениеPATCH /items/1200
DELETEУдалитьDELETE /items/1204
HEADGET без телаHEAD /items200
OPTIONSИнформация о методахOPTIONS /items200

Ключевой момент: FastAPI автоматически генерирует интерактивную документацию (Swagger UI) на /docs, где видны все методы, параметры и примеры использования!

Как указать тип HTTP запроса в FastAPI? | PrepBro