Lesson 22 of 26

Урок 22 — HTTP методы: GET, POST, PUT, PATCH, DELETE

Название: HTTP методы — как клиент говорит серверу что делать
Описание: Подробно разбираем все основные HTTP методы: GET, POST, PUT, PATCH, DELETE. Объясняем семантику, идемпотентность, кеширование и как правильно тестировать каждый метод.
Почему это важно для QA: Знание HTTP методов — обязательная база для тестирования API. Без понимания разницы между PUT и PATCH, идемпотентности и безопасности — невозможно грамотно проектировать тест-кейсы.


1. Что такое HTTP метод

HTTP метод (или HTTP verb) — это слово в запросе, которое сообщает серверу, какое действие нужно выполнить с ресурсом.

GET    /api/users/42    → получить пользователя #42
POST   /api/users       → создать нового пользователя
PUT    /api/users/42    → полностью заменить пользователя #42
PATCH  /api/users/42    → частично обновить пользователя #42
DELETE /api/users/42    → удалить пользователя #42

2. Ключевые свойства методов

Идемпотентность

Идемпотентный метод — это метод, при повторном вызове которого результат не меняется.

Идемпотентный: запрос можно повторить N раз — результат один и тот же
GET  /users/42 → ответ всегда одинаков, ничего не меняется
PUT  /users/42 → при повторном запросе с теми же данными — результат тот же
DELETE /users/42 → первый вызов удаляет, второй возвращает 404 (результат не меняется — пользователь всё равно удалён)

НЕ идемпотентный:
POST /users → каждый вызов создаёт НОВОГО пользователя
PATCH /users/42 с { "counter": counter + 1 } → каждый вызов меняет значение

Безопасность метода

Безопасный метод не изменяет состояние сервера.

Безопасные:    GET, HEAD, OPTIONS
Небезопасные:  POST, PUT, PATCH, DELETE

Таблица свойств

МетодБезопасныйИдемпотентныйКешируемый
GET
POST❌ (обычно)
PUT
PATCH❌ (обычно)
DELETE

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

Назначение

Получить ресурс или список ресурсов. Не изменяет данные на сервере.

Примеры

GET /api/users             → список всех пользователей
GET /api/users/42          → пользователь с ID 42
GET /api/users?role=admin  → пользователи с фильтром по роли
GET /api/users?page=2&limit=10  → пагинация

Ответы

200 OK           → успешно, данные в теле ответа
404 Not Found    → ресурс не существует
401 Unauthorized → нужна авторизация
403 Forbidden    → нет доступа

Что тестировать

✓ Корректный ответ при существующем ID
✓ 404 при несуществующем ID
✓ Структура ответа (все нужные поля присутствуют)
✓ Пагинация (page, limit работают корректно)
✓ Фильтрация (параметры query применяются)
✓ Сортировка работает корректно
✓ Данные актуальны (после создания GET возвращает новый ресурс)
✓ Авторизация (401 без токена, 403 при недостаточных правах)

Пример теста в Postman (Tests)

javascriptjavascript
pm.test("GET /users/1 → 200 OK", () => {
  pm.response.to.have.status(200);
});

pm.test("Ответ содержит корректную структуру пользователя", () => {
  const user = pm.response.json();
  pm.expect(user).to.have.property("id");
  pm.expect(user).to.have.property("name");
  pm.expect(user).to.have.property("email");
  pm.expect(user.id).to.equal(1);
});

4. POST — создание ресурса

Назначение

Создать новый ресурс на сервере. Не идемпотентен — каждый вызов создаёт новый ресурс.

Примеры

POST /api/users
Content-Type: application/json

{
  "name": "Иван Петров",
  "email": "ivan@test.com",
  "password": "SecurePass123"
}

Ответы

201 Created      → ресурс успешно создан (в ответе — созданный ресурс + Location заголовок)
400 Bad Request  → невалидные данные
409 Conflict     → ресурс уже существует (email занят)
422 Unprocessable Entity → данные прошли синтаксис, но нарушают бизнес-правила

Что тестировать

✓ 201 при корректных данных
✓ Ресурс действительно создан (GET после POST возвращает созданный ресурс)
✓ 400 при невалидных данных (пустые обязательные поля)
✓ 400 при неверном формате (email без @)
✓ 409 при дублировании уникального поля (email уже есть)
✓ Повторный POST создаёт НОВЫЙ ресурс (не идемпотентен)
✓ Location заголовок содержит URL созданного ресурса

5. PUT — полная замена ресурса

Назначение

Полностью заменить ресурс. Если отправить PUT с частью полей — остальные поля удаляются или сбрасываются в null.

Пример

PUT /api/users/42
Content-Type: application/json

{
  "id": 42,
  "name": "Иван Петров",
  "email": "ivan.new@test.com",
  "role": "admin",
  "createdAt": "2026-01-01"
}

Важно: если не включить поле role — оно будет сброшено!

PUT vs POST

POST /api/users       → создаёт нового пользователя (ID присваивает сервер)
PUT  /api/users/42    → заменяет пользователя #42 целиком (ID известен)

Идемпотентность PUT

PUT /users/42 { name: "Иван" } → пользователь #42 стал "Иван"
PUT /users/42 { name: "Иван" } → пользователь #42 всё ещё "Иван" (без изменений)
→ идемпотентен: повторный запрос не меняет результат

Что тестировать

✓ 200 при корректных данных
✓ Все поля объекта обновляются
✓ Поля, не переданные в запросе, сбрасываются (не наследуются)
✓ 404 при несуществующем ID
✓ 400 при отсутствии обязательных полей
✓ Идемпотентность (повторный запрос с теми же данными даёт тот же результат)

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

Назначение

Обновить только указанные поля ресурса, не затрагивая остальные.

Пример

PATCH /api/users/42
Content-Type: application/json

{
  "email": "ivan.updated@test.com"
}

Поля name, role, createdAt остаются без изменений.

PUT vs PATCH — ключевое отличие

Состояние пользователя #42:
{ id: 42, name: "Иван", email: "old@test.com", role: "user" }

PUT /users/42 { name: "Иван", role: "admin" }
→ Результат: { id: 42, name: "Иван", email: null, role: "admin" }
   email = null! (поле не было передано)

PATCH /users/42 { role: "admin" }
→ Результат: { id: 42, name: "Иван", email: "old@test.com", role: "admin" }
   Только role изменился, остальное — без изменений

Что тестировать

✓ 200 при частичном обновлении
✓ Переданные поля обновляются
✓ НЕ переданные поля остаются без изменений
✓ 404 при несуществующем ID
✓ 400 при невалидных значениях полей
✓ Нельзя изменить readonly поля (id, createdAt)

7. DELETE — удаление ресурса

Назначение

Удалить ресурс. Идемпотентен — повторный DELETE на уже удалённый ресурс возвращает 404 (ресурс всё равно отсутствует).

Примеры

DELETE /api/users/42        → удалить пользователя #42
DELETE /api/orders/99       → удалить заказ #99

Ответы

200 OK           → удалён (с телом ответа — описание)
204 No Content   → удалён (без тела ответа) ← наиболее распространённый
404 Not Found    → ресурс не существует
403 Forbidden    → нет прав на удаление
409 Conflict     → нельзя удалить (есть зависимые объекты)

Что тестировать

✓ 204 / 200 при успешном удалении
✓ GET после DELETE возвращает 404 (ресурс действительно удалён)
✓ 404 при попытке удалить несуществующий ресурс
✓ 403 при недостаточных правах (обычный пользователь удаляет чужой ресурс)
✓ Каскадное удаление (если удаляем пользователя — что с его заказами?)
✓ Идемпотентность (повторный DELETE → 404, а не 500)

8. Другие HTTP методы

МетодОписаниеИспользование
HEADКак GET, но без тела ответаПроверить существование ресурса, получить заголовки
OPTIONSКакие методы поддерживает эндпоинтCORS pre-flight запросы
CONNECTСоздать туннельПрокси-серверы, HTTPS через HTTP-прокси
TRACEОтладочный эхо-запросДиагностика (обычно отключён в production)

9. Сводная таблица

МетодДействиеТело запросаОтветИдемпотентБезопасный
GETПолучитьНет200 + данные
POSTСоздатьДа201 + созданный ресурс
PUTЗаменить целикомДа (весь объект)200 / 204
PATCHОбновить частичноДа (только изменяемые поля)200
DELETEУдалитьНет / Да200 / 204

10. Типичные тест-кейсы для API

Матрица тестирования CRUD

Ресурс: /api/users

CREATE (POST):
├── TC-01: Создать с валидными данными → 201
├── TC-02: Создать без обязательного поля → 400
├── TC-03: Создать с дублирующимся email → 409
└── TC-04: Повторный POST с теми же данными → снова 201 (новый пользователь)

READ (GET):
├── TC-05: Получить список → 200 + массив
├── TC-06: Получить по ID → 200 + объект
├── TC-07: Несуществующий ID → 404
└── TC-08: Без авторизации → 401

UPDATE (PUT / PATCH):
├── TC-09: PUT с полным объектом → 200, все поля обновлены
├── TC-10: PUT без поля → поле сброшено в null
├── TC-11: PATCH с одним полем → только это поле изменилось
└── TC-12: PATCH несуществующего → 404

DELETE:
├── TC-13: Удалить существующий → 204
├── TC-14: GET после DELETE → 404
├── TC-15: Повторный DELETE → 404 (не 500)
└── TC-16: Удалить чужой ресурс → 403

Итог

GET    = получить (безопасный, идемпотентный, кешируемый)
POST   = создать (не идемпотентный, создаёт новый ресурс каждый раз)
PUT    = заменить целиком (идемпотентный, все поля обязательны)
PATCH  = обновить частично (только нужные поля, остальные не трогает)
DELETE = удалить (идемпотентный, повторный DELETE → 404)

Ключевое отличие PUT vs PATCH:
PUT   → "замени пользователя" (нужен весь объект)
PATCH → "обнови email пользователя" (только изменяемое поле)