В чем разница между post и put?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Различие между HTTP методами POST и PUT
Понимание разницы между POST и PUT критично для тестирования REST API. Хотя оба метода отправляют данные на сервер, они используются для совершенно разных операций и имеют разную семантику.
Ключевые различия
POST — создание нового ресурса
Назначение: POST используется для создания НОВОГО ресурса на сервере. Сервер определяет, где будет расположен этот ресурс и какой ему присвоить ID.
Характеристики:
- Идемпотентность: НЕ идемпотентен — каждый запрос создаёт новый ресурс
- Результат: Каждый POST запрос может привести к разному результату
- ID ресурса: Определяется сервером
- Ответ сервера: Обычно 201 (Created) с Location заголовком, где расположен новый ресурс
- URI: POST обычно к коллекции:
POST /api/v1/users
Пример POST:
POST /api/v1/users HTTP/1.1
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
Ответ (201 Created):
{
"id": "123",
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-03-23T10:00:00Z"
}
Location: /api/v1/users/123
Поведение при повторных вызовах:
Первый POST → создаёт пользователя ID 123
Второй POST с теми же данными → создаёт пользователя ID 124
Третий POST → создаёт пользователя ID 125
Результат: 3 разных пользователя, но с одинаковыми данными
PUT — полное обновление существующего ресурса
Назначение: PUT используется для ОБНОВЛЕНИЯ или ЗАМЕНЫ целиком существующего ресурса. Клиент указывает точный URI ресурса, который нужно обновить.
Характеристики:
- Идемпотентность: Идемпотентен — множественные одинаковые запросы дают один и тот же результат
- Результат: Каждый PUT запрос приводит к одному и тому же состоянию
- ID ресурса: Определяется клиентом (указывается в URL)
- Ответ сервера: Обычно 200 (OK) или 204 (No Content)
- URI: PUT обычно к конкретному ресурсу:
PUT /api/v1/users/123 - Заменяет: Полностью заменяет ресурс (все поля)
Пример PUT:
PUT /api/v1/users/123 HTTP/1.1
Content-Type: application/json
{
"name": "Jane Doe",
"email": "jane@example.com"
}
Ответ (200 OK):
{
"id": "123",
"name": "Jane Doe",
"email": "jane@example.com",
"updated_at": "2024-03-23T11:00:00Z"
}
Поведение при повторных вызовах:
Первый PUT на /users/123 → обновляет пользователя 123
Второй PUT на /users/123 с теми же данными → результат идентичен первому
Третий PUT на /users/123 → результат вновь идентичен
Результат: пользователь 123 обновлён один раз, потом состояние не меняется
Таблица сравнения
| Аспект | POST | PUT |
|---|---|---|
| Операция | Создание | Обновление/Замена |
| Идемпотентность | НЕ идемпотентен | Идемпотентен |
| URI | Коллекция (POST /users) | Ресурс (PUT /users/123) |
| ID определяет | Сервер | Клиент |
| Статус код | 201 Created | 200 OK / 204 No Content |
| Повторные вызовы | Создают новый ресурс | Не изменяют результат |
| Данные | Добавляют к коллекции | Заменяют весь ресурс |
Практические примеры из тестирования
Сценарий 1: Регистрация пользователя
Тест POST /api/v1/auth/register:
Первый запрос:
POST /api/v1/auth/register
{
"email": "user@example.com",
"password": "secret123"
}
Ответ: 201 Created, новый user ID = 1001
Второй запрос (с теми же данными):
Ответ: 201 Created, новый user ID = 1002 (новый пользователь!)
Вывод: POST создал ДВА разных пользователя
Этот баг можно выявить через тестирование!
Сценарий 2: Обновление профиля пользователя
Тест PUT /api/v1/users/123:
Первый запрос:
PUT /api/v1/users/123
{
"name": "John Updated",
"age": 30
}
Ответ: 200 OK
Данные пользователя 123: name="John Updated", age=30
Второй запрос (с теми же данными):
Ответ: 200 OK
Данные пользователя 123: name="John Updated", age=30 (без изменений)
Вывод: Состояние идентично, PUT идемпотентен
Важный нюанс: PATCH
Помимо PUT, существует метод PATCH:
- PUT — ПОЛНОЕ обновление (заменяет весь ресурс)
- PATCH — ЧАСТИЧНОЕ обновление (обновляет отдельные поля)
Пример:
Пользователь ID 123 имеет:
{
"name": "John",
"email": "john@example.com",
"age": 30
}
PUT запрос с {"name": "Jane"}:
Результат: {"name": "Jane", "email": null, "age": null}
(остальные поля стираются)
PATCH запрос с {"name": "Jane"}:
Результат: {"name": "Jane", "email": "john@example.com", "age": 30}
(только name обновляется, остальное остаётся)
Как это влияет на тестирование API
Тест-кейсы для POST:
1. Создание нового ресурса
✓ Должен вернуть 201 Created
✓ Должен вернуть Location заголовок
✓ Данные должны быть сохранены
2. Дублирование (повторный POST с теми же данными)
✓ Должен создать ДРУГОЙ ресурс
✓ Должен быть другой ID
✓ Общее количество ресурсов увеличится
3. Обязательные поля
✓ POST без обязательного поля должен вернуть 400 Bad Request
Тест-кейсы для PUT:
1. Обновление существующего ресурса
✓ Должен вернуть 200 OK или 204 No Content
✓ Данные должны быть полностью обновлены
✓ ID не должен измениться
2. Идемпотентность
✓ Два одинаковых PUT запроса → одинаковый результат
✓ Состояние не меняется после первого успешного запроса
✓ Количество ресурсов не растёт
3. Обновление несуществующего ресурса
✓ PUT на несуществующий ID → обычно 404 Not Found
✓ Или в некоторых API — создание нового ресурса с этим ID
4. Частичное обновление
✓ PUT должен заменить ВСЕ поля
✓ Отсутствующие поля в запросе → обнуляются или ошибка
✓ Для частичного обновления использовать PATCH
Частые ошибки в реализации API
❌ Ошибка 1: POST выглядит как PUT
Проблема: POST создаёт дублирующиеся ресурсы
Причина: Нет проверки на существование в коде
Тест выявит: Отправить один POST дважды → проверить ID
❌ Ошибка 2: PUT не полностью обновляет
Проблема: PUT не обновляет отдельные поля
Причина: Код использует частичное обновление вместо полного
Тест выявит: PUT с одним полем → проверить остальные
❌ Ошибка 3: Неправильные статус коды
Проблема: POST возвращает 200 вместо 201
Проблема: PUT возвращает 201 вместо 200/204
Тест выявит: Проверка ровно нужного статус кода
Заключение
Разница между POST и PUT — это фундаментальная концепция REST API:
- POST — «добавить новое» (не идемпотентен)
- PUT — «заменить существующее» (идемпотентен)
Для QA это означает совершенно разные сценарии тестирования и разные ожидания от поведения API.