Какие методы в http передают тело запроса?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Какие методы HTTP передают тело запроса
В HTTP тело запроса (request body) может передаваться различными методами, но не все методы предназначены для этого. Разберу каждый.
1. POST
Основной метод для отправки данных.
Назначение: создание нового ресурса на сервере.
import requests
# JSON body
response = requests.post(
"https://api.example.com/users",
json={"name": "John", "email": "john@example.com"}
)
# Эквивалентно
response = requests.post(
"https://api.example.com/users",
headers={"Content-Type": "application/json"},
data='{"name": "John", "email": "john@example.com"}'
)
# Form data
response = requests.post(
"https://api.example.com/login",
data={"username": "john", "password": "secret"}
)
# Файл
with open('file.pdf', 'rb') as f:
response = requests.post(
"https://api.example.com/upload",
files={"file": f}
)
Идемпотентность: ❌ НЕ идемпотентный (несколько вызовов = несколько ресурсов).
2. PUT
Метод для обновления или полной замены ресурса.
# Обновить весь ресурс (полная замена)
response = requests.put(
"https://api.example.com/users/1",
json={
"name": "John Updated",
"email": "john.updated@example.com",
"age": 30
}
)
# Тело ОБЯЗАТЕЛЬНО присутствует
# Это отличает PUT от DELETE
Идемпотентность: ✅ Идемпотентный (несколько одинаковых вызовов = один результат).
Важно: PUT должен быть идемпотентным — отправить один раз или 100 раз даёт один результат.
3. PATCH
Метод для частичного обновления ресурса (patch = заплатка).
# Обновить только некоторые поля
response = requests.patch(
"https://api.example.com/users/1",
json={
"email": "new.email@example.com" # Только этот
}
)
# Сравнение:
# PUT: обновить ВСЕ поля
# PATCH: обновить НЕКОТОРЫЕ поля
Идемпотентность: ✅ Идемпотентный (теоретически, но зависит от реализации).
Различие PATCH и PUT:
# PUT: полная замена
PUT /users/1 ← {"name": "John", "email": "john@example.com"}
# Результат: все поля = переданные значения
# PATCH: частичное обновление
PATCH /users/1 ← {"email": "new@example.com"}
# Результат: email изменился, остальное осталось
4. DELETE
В стандарте HTTP DELETE МОЖЕТ иметь тело, но на практике редко используется.
# DELETE обычно БЕЗ тела (identifier в URL)
response = requests.delete(
"https://api.example.com/users/1"
)
# DELETE с телом (редко, но возможно)
response = requests.delete(
"https://api.example.com/users/bulk",
json={"ids": [1, 2, 3, 4, 5]} # Удалить несколько
)
Идемпотентность: ✅ Идемпотентный (удалить несуществующий ресурс = то же, что уже удаленный).
5. GET
Метод НЕ предназначен для передачи тела.
# ❌ Неправильно (но технически возможно)
response = requests.get(
"https://api.example.com/search",
json={"query": "python"} # Тело есть, но игнорируется
)
# ✅ Правильно: параметры в URL
response = requests.get(
"https://api.example.com/search?q=python&limit=10"
)
# ✅ Или с params
response = requests.get(
"https://api.example.com/search",
params={"q": "python", "limit": 10}
)
Проблема: некоторые старые сервера игнорируют body в GET, некоторые отказывают с ошибкой.
6. HEAD
Как GET, но без body в ответе. НЕ передаёт тело.
# Проверить, существует ли ресурс
response = requests.head("https://api.example.com/users/1")
if response.status_code == 200:
print("Ресурс существует")
7. OPTIONS
Запросить допустимые методы для ресурса. НЕ передаёт тело.
response = requests.options("https://api.example.com/users")
print(response.headers.get("Allow")) # POST, GET, DELETE, ...
Таблица методов
| Метод | Тело | Идемпотентный | Назначение | Безопасный |
|---|---|---|---|---|
| GET | ❌ | ✅ | Получить ресурс | ✅ |
| POST | ✅ | ❌ | Создать ресурс | ❌ |
| PUT | ✅ | ✅ | Полное обновление | ❌ |
| PATCH | ✅ | ✅ | Частичное обновление | ❌ |
| DELETE | ⚠️ (редко) | ✅ | Удалить ресурс | ❌ |
| HEAD | ❌ | ✅ | Как GET, но без body | ✅ |
| OPTIONS | ❌ | ✅ | Запросить методы | ✅ |
Практические примеры в FastAPI
from fastapi import FastAPI, Body
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
email: str
# POST: создать
@app.post("/users")
async def create_user(user: User):
return {"id": 1, **user.dict()}
# PUT: полное обновление
@app.put("/users/{user_id}")
async def update_user(user_id: int, user: User):
return {"id": user_id, **user.dict()}
# PATCH: частичное обновление
@app.patch("/users/{user_id}")
async def patch_user(user_id: int, user: dict = Body(...)):
# user может быть {"email": "new@example.com"}
return {"id": user_id, "updated": user}
# DELETE: удалить
@app.delete("/users/{user_id}")
async def delete_user(user_id: int):
return {"deleted": user_id}
# GET: получить
@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"id": user_id, "name": "John"}
Ошибки при использовании
Ошибка 1: GET с телом
# ❌ Не делай так
response = requests.get(
"https://api.example.com/search",
json={"query": "python"}
)
# ✅ Делай так
response = requests.get(
"https://api.example.com/search",
params={"query": "python"}
)
Ошибка 2: POST вместо PUT/PATCH
# ❌ Неправильно: POST для обновления
@app.post("/users/{user_id}")
async def update_user_wrong(user_id: int, user: User):
pass # Это создание, не обновление!
# ✅ Правильно
@app.put("/users/{user_id}")
async def update_user(user_id: int, user: User):
pass # Обновление
Ошибка 3: DELETE с телом (неоднозначно)
# ⚠️ Избегай: некоторые сервера не поддерживают
response = requests.delete(
"https://api.example.com/users/1",
json={"reason": "inactive"}
)
# ✅ Лучше: параметр в URL
response = requests.delete(
"https://api.example.com/users/1?reason=inactive"
)
Когда тело обязательно?
| Сценарий | Метод | Тело | Пример |
|---|---|---|---|
| Создать ресурс | POST | ✅ | POST /users с JSON user |
| Обновить всё | PUT | ✅ | PUT /users/1 с полным user |
| Обновить часть | PATCH | ✅ | PATCH /users/1 с {"email": "..."} |
| Удалить | DELETE | ❌ | DELETE /users/1 |
| Получить | GET | ❌ | GET /users?id=1 |
| Поиск (специально) | POST | ✅ | POST /search с query |
Заключение
Методы с телом:
- POST — создание (НЕ идемпотентный)
- PUT — полное обновление (идемпотентный)
- PATCH — частичное обновление (идемпотентный)
- DELETE — редко, для batch операций
Методы БЕЗ тела:
- GET — получение
- HEAD — как GET, но без body
- OPTIONS — запрос методов
Золотое правило: используй правильный метод для правильной задачи. REST API становится понятнее, а код — надежнее.