Методы HTTP: GET, POST, PUT, PATCH, DELETE

Методы HTTP: GET, POST, PUT, PATCH, DELETE (REST API) REST API

Привет! В REST API каждый HTTP-метод имеет своё предназначение. Понимание этих методов — основа для создания правильных и удобных API.

В этой статье мы разберём:

  • GET — получение данных
  • POST — создание данных
  • PUT — полное обновление
  • PATCH — частичное обновление
  • DELETE — удаление данных

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Базовое понимание HTTP
  • Установленный FastAPI

Совет: Правильное использование методов HTTP делает API интуитивно понятным.

Основная часть

GET — получение данных

GET используется для получения данных. Он не должен изменять состояние сервера.

from fastapi import FastAPI

app = FastAPI()

# Список всех пользователей
@app.get("/users")
def get_users():
    return {"users": [{"id": 1, "name": "Анна"}, {"id": 2, "name": "Иван"}]}

# Получение одного пользователя
@app.get("/users/{user_id}")
def get_user(user_id: int):
    return {"id": user_id, "name": f"Пользователь {user_id}"}

Особенности GET:

  • Не изменяет данные
  • Можно кешировать
  • Параметры передаются в URL

POST — создание данных

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

from fastapi import FastAPI, HTTPException

app = FastAPI()

# Заглушка БД
users_db = {}
next_id = 1

@app.post("/users")
def create_user(name: str):
    global next_id
    user = {"id": next_id, "name": name}
    users_db[next_id] = user
    next_id += 1
    return {"message": "Пользователь создан", "user": user}

Особенности POST:

  • Создаёт новый ресурс
  • Не идемпотентен (повторный запрос создаёт новый ресурс)
  • Данные передаются в теле запроса

PUT — полное обновление

PUT используется для полного обновления ресурса. Заменяет весь объект.

@app.put("/users/{user_id}")
def update_user(user_id: int, name: str):
    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="Пользователь не найден")

    user = {"id": user_id, "name": name}
    users_db[user_id] = user
    return {"message": "Пользователь обновлён", "user": user}

Особенности PUT:

  • Полное обновление ресурса
  • Идемпотентен (повторный запрос даёт тот же результат)
  • Если ресурса нет — можно создать (не рекомендуется)

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

PATCH используется для частичного обновления ресурса. Изменяет только указанные поля.

from fastapi import FastAPI, HTTPException

app = FastAPI()

# Заглушка БД
users_db = {
    1: {"id": 1, "name": "Анна", "age": 25},
    2: {"id": 2, "name": "Иван", "age": 30}
}

@app.patch("/users/{user_id}")
def patch_user(user_id: int, name: str = None, age: int = None):
    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="Пользователь не найден")

    user = users_db[user_id]
    if name is not None:
        user["name"] = name
    if age is not None:
        user["age"] = age

    return {"message": "Пользователь обновлён", "user": user}

Особенности PATCH:

  • Частичное обновление
  • Не обязательно идемпотентен
  • Экономит трафик

DELETE — удаление данных

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

@app.delete("/users/{user_id}")
def delete_user(user_id: int):
    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="Пользователь не найден")

    deleted_user = users_db.pop(user_id)
    return {"message": "Пользователь удалён", "deleted": deleted_user}

Особенности DELETE:

  • Удаляет ресурс
  • Идемпотентен (повторный запрос возвращает 404)
  • Обычно возвращает 204 No Content или 200 OK

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

МетодНазначениеИдемпотентенТело запроса
GETПолучениеДаНет
POSTСозданиеНетДа
PUTПолное обновлениеДаДа
PATCHЧастичное обновлениеНетДа
DELETEУдалениеДаНет

Совет: Идемпотентность означает, что повторный запрос не изменяет состояние сервера.

Полный пример

from fastapi import FastAPI, HTTPException

app = FastAPI()

# Заглушка БД
users_db = {
    1: {"id": 1, "name": "Анна", "age": 25},
    2: {"id": 2, "name": "Иван", "age": 30}
}
next_id = 3

# GET — получить всех пользователей
@app.get("/users")
def get_users():
    return {"users": list(users_db.values())}

# GET — получить одного пользователя
@app.get("/users/{user_id}")
def get_user(user_id: int):
    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="Пользователь не найден")
    return users_db[user_id]

# POST — создать пользователя
@app.post("/users")
def create_user(name: str, age: int):
    global next_id
    user = {"id": next_id, "name": name, "age": age}
    users_db[next_id] = user
    next_id += 1
    return {"message": "Пользователь создан", "user": user}

# PUT — полное обновление
@app.put("/users/{user_id}")
def update_user(user_id: int, name: str, age: int):
    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="Пользователь не найден")
    user = {"id": user_id, "name": name, "age": age}
    users_db[user_id] = user
    return {"message": "Пользователь обновлён", "user": user}

# PATCH — частичное обновление
@app.patch("/users/{user_id}")
def patch_user(user_id: int, name: str = None, age: int = None):
    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="Пользователь не найден")
    user = users_db[user_id]
    if name is not None:
        user["name"] = name
    if age is not None:
        user["age"] = age
    return {"message": "Пользователь обновлён", "user": user}

# DELETE — удаление пользователя
@app.delete("/users/{user_id}")
def delete_user(user_id: int):
    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="Пользователь не найден")
    deleted = users_db.pop(user_id)
    return {"message": "Пользователь удалён", "deleted": deleted}

Статус-коды для каждого метода

МетодУспехОшибка
GET200 OK404 Not Found
POST201 Created400 Bad Request
PUT200 OK404 Not Found
PATCH200 OK404 Not Found
DELETE200 OK / 204 No Content404 Not Found

Задачи для закрепления

Задача 1. Создай эндпоинт GET для получения списка товаров.

Задача 2. Создай эндпоинт POST для создания товара.

Задача 3. Создай эндпоинт PUT для обновления товара.

Задача 4. Создай эндпоинт DELETE для удаления товара.

Задача 5. Чем отличается PUT от PATCH?

Ответы:

Задача 1.

@app.get("/products")
def get_products():
    return {"products": []}

Задача 2.

@app.post("/products")
def create_product(name: str):
    return {"message": "Товар создан"}

Задача 3.

@app.put("/products/{product_id}")
def update_product(product_id: int, name: str):
    return {"message": f"Товар {product_id} обновлён"}

Задача 4.

@app.delete("/products/{product_id}")
def delete_product(product_id: int):
    return {"message": f"Товар {product_id} удалён"}

Задача 5.

# PUT — полное обновление
# PATCH — частичное обновление

Нюансы и подводные камни

  • GET — не должен изменять состояние сервера (идемпотентен).
  • POST — не идемпотентен. Повторный запрос создаёт новый ресурс.
  • PUT — идемпотентен. Повторный запрос не изменяет состояние.
  • PATCH — не обязательно идемпотентен.
  • DELETE — идемпотентен. Повторный запрос возвращает 404.
  • PUT заменяет весь ресурс, PATCH — только указанные поля.
  • В FastAPI методы указываются в декораторе: @app.get()@app.post()@app.put()@app.patch()@app.delete().

Частые ошибки и как их избежать

Ошибка 1: PUT для частичного обновления

Используй PUT только для полной замены ресурса.

Ошибка 2: POST для идемпотентных операций

Используй PUT или PATCH для обновлений.

Ошибка 3: GET для изменения данных

GET должен быть безопасным и идемпотентным.

Шпаргалка

МетодКак пишется в FastAPI
GET@app.get("/path")
POST@app.post("/path")
PUT@app.put("/path")
PATCH@app.patch("/path")
DELETE@app.delete("/path")

Заключение

Сегодня мы:

  • Изучили методы HTTP
  • Разобрали GET, POST, PUT, PATCH, DELETE
  • Узнали про идемпотентность
  • Примеры с FastAPI

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×