Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое PATCH метод HTTP?
PATCH — это метод HTTP-запроса, предназначенный для частичного обновления ресурса на сервере. В отличие от PUT, который заменяет ресурс целиком, PATCH позволяет внести изменения только в указанные поля или части данных, оставляя остальную часть ресурса неизменной. Этот метод был стандартизирован в RFC 5789 и играет ключевую роль в современных RESTful API, где эффективность передачи данных критически важна.
Ключевые особенности PATCH:
- Частичное обновление: Клиент отправляет только те данные, которые необходимо изменить, а не полное представление ресурса.
- Идемпотентность (условно): Сам по себе метод PATCH не является идемпотентным по спецификации. Однако его можно сделать таковым, если использовать форматы, гарантирующие предсказуемый результат при повторе запроса (например, JSON Patch).
- Безопасность: Как и другие методы изменения данных (PUT, POST, DELETE), PATCH не является безопасным.
- Формат тела запроса: Не предписан строго. Для корректной работы клиент и сервер должны договориться о формате применяемых изменений (media type).
Сравнение PATCH с PUT и POST
| Метод | Назначение | Тело запроса | Идемпотентность |
|---|---|---|---|
| POST | Создание ресурса или выполнение действия | Данные для создания | Нет |
| PUT | Полная замена ресурса по указанному URI | Новое, полное представление ресурса | Да |
| PATCH | Частичное обновление ресурса по указанному URI | Инструкции или дельта изменений | Зависит от формата |
Форматы данных для PATCH
Стандарт определяет метод, но не формат данных. На практике используются несколько популярных форматов:
- JSON Merge Patch (RFC 7396): Простой формат, похожий на частичный JSON-объект. Для удаления поля используется значение
null.// Запрос PATCH /users/123 { "age": 31, "address": { "city": "Москва" }, "nickname": null } // Результат: поле 'age' обновлено, вложенный 'city' обновлен, поле 'nickname' удалено.
**Недостаток:** Не поддерживает явные операции с массивами (например, добавление элемента в конкретную позицию).
- JSON Patch (RFC 6902): Более мощный и стандартизированный формат, представляющий собой массив операций. Явно определяет действия: add, remove, replace, move, copy, test.
// Запрос PATCH /users/123 // Content-Type: application/json-patch+json [ { "op": "replace", "path": "/age", "value": 31 }, { "op": "add", "path": "/address/city", "value": "Москва" }, { "op": "remove", "path": "/nickname" }, { "op": "replace", "path": "/hobbies/1", "value": "тестирование" } ]
**Преимущество:** Полная поддержка массивов, атомарность (все операции применяются как единое целое), идемпотентность.
Практическое применение в тестировании (QA)
Как QA-инженер, вы должны понимать и тестировать PATCH-запросы, проверяя:
- Корректность логики обновления: Меняется ли только то, что указано в запросе?
- Валидация данных: Обрабатываются ли ошибки при попытке обновить несуществующее поле или передать невалидные данные?
- Обработка форматов: Корректно ли API работает с
application/merge-patch+jsonи/илиapplication/json-patch+json? - Идемпотентность (если заявлена): Приводит ли повторная отправка одинакового PATCH-запроса к тому же состоянию ресурса?
- Безопасность и авторизация: Может ли пользователь изменить только свои данные? Проверяется ли право на изменение каждого поля?
- Атомарность: Если в массиве операций (JSON Patch) одна операция невалидна, применяются ли предыдущие? Ожидаемое поведение — откат всех изменений (все или ничего).
Пример тест-кейса для PATCH (Python + pytest + requests)
import pytest
import requests
BASE_URL = "https://api.example.com/v1"
USER_ID = 123
HEADERS = {"Content-Type": "application/json"}
def test_patch_user_partial_update():
"""Тест частичного обновления данных пользователя с помощью PATCH."""
# 1. Подготовка: Получаем исходные данные пользователя
user_before = requests.get(f"{BASE_URL}/users/{USER_ID}").json()
# 2. Действие: Отправляем PATCH-запрос на изменение только города
patch_data = {
"address": {
"city": "Казань"
}
}
response = requests.patch(
f"{BASE_URL}/users/{USER_ID}",
json=patch_data,
headers=HEADERS
)
# 3. Проверки
assert response.status_code == 200
user_after = response.json()
# Изменилось только поле city в address
assert user_after["address"]["city"] == "Казань"
assert user_after["address"]["street"] == user_before["address"]["street"]
# Все остальные поля остались прежними
assert user_after["name"] == user_before["name"]
assert user_after["age"] == user_before["age"]
def test_patch_with_invalid_data():
"""Тест обработки ошибки при попытке обновить несуществующее поле."""
patch_data = {
"nonExistentField": "value"
}
response = requests.patch(
f"{BASE_URL}/users/{USER_ID}",
json=patch_data,
headers=HEADERS
)
# Ожидаем 400 Bad Request или 422 Unprocessable Entity
assert response.status_code in [400, 422]
error_response = response.json()
assert "error" in error_response
assert "nonExistentField" in error_response["message"]
Вывод
PATCH — это мощный и эффективный инструмент для оптимизации сетевого взаимодействия в API. Его правильное использование снижает нагрузку на сеть и упрощает клиентскую логику. Для QA-инженера глубокое понимание этого метода, его отличий от PUT, а также форматов данных (особенно JSON Patch) является важной частью компетенции при тестировании современных RESTful и GraphQL API. Тестирование должно покрывать не только "счастливый путь", но и обработку ошибок, атомарность операций и вопросы безопасности.