← Назад к вопросам

Какой вид запроса лучше использовать для изменения статуса объекта?

1.0 Junior🔥 181 комментариев
#Soft Skills и личные качества

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Вид запроса для изменения статуса объекта

Это классический вопрос, который показывает, насколько хорошо аналитик понимает REST архитектуру и различия между HTTP методами. Расскажу о разных подходах, их плюсах и минусах, и когда использовать каждый.

HTTP методы: краткий обзор

GET — получить данные (безопасен, идемпотентен) POST — создать новый ресурс (не идемпотентен) PUT — заменить весь ресурс (идемпотентен) PATCH — частичное обновление ресурса (в идеале идемпотентен) DELETE — удалить ресурс (идемпотентен)

Для изменения статуса есть несколько подходов, и каждый имеет своё место.

Вариант 1: PUT — замена всего ресурса

Пример запроса:

PUT /api/v1/orders/123
Content-Type: application/json

{
  "id": 123,
  "product": "Laptop",
  "price": 999.99,
  "status": "shipped"
}

Как это работает: Клиент отправляет полный объект заказа со всеми полями, включая новый статус. Сервер заменяет весь объект.

Преимущества:

  • Идеально для REST — PUT по определению это замена ресурса
  • Простота — не нужна специальная логика, просто обновляешь объект целиком
  • Идемпотентность — если отправить один и тот же запрос дважды, результат будет одинаковый
  • Явность — в запросе видны все текущие значения

Недостатки:

  • Требует передачи всех данных — нужно отправить весь объект, даже если меняется только статус
  • Вероятность потери данных — если клиент забыл одно поле, оно будет потеряно
  • Bandwidth — больше данных в запросе
  • Race conditions — если два клиента одновременно обновляют, может быть конфликт

Вариант 2: PATCH — частичное обновление

Пример запроса:

PATCH /api/v1/orders/123
Content-Type: application/json

{
  "status": "shipped"
}

Как это работает: Клиент отправляет только изменяемые поля. Сервер применяет эти изменения к существующему объекту.

Преимущества:

  • Минимум данных — отправляем только то, что меняется
  • Безопаснее — не потеряем существующие данные
  • Efficiency — меньше трафика
  • Интуитивнее — нужно изменить статус? Отправь только статус

Недостатки:

  • Идемпотентность спорна — PATCH может быть неидемпотентным, если не реализовано аккуратно
  • Сложнее реализовать — нужна логика для частичного обновления
  • JSON Patch стандарт — нужно договориться о формате (RFC 6902)
  • Не все фреймворки хорошо поддерживают — нужна дополнительная работа

Вариант 3: POST к операции (специальный endpoint)

Пример запроса:

POST /api/v1/orders/123/ship
Content-Type: application/json

{
  "tracking_number": "1234567890"
}

Как это работает: Вместо изменения поля статуса, клиент вызывает специальную операцию на ресурсе.

Преимущества:

  • Семантика действия — явно понимаем, что произойдёт: отправка заказа
  • Логика события — сервер может выполнить дополнительные действия (отправить письмо, обновить инвентарь)
  • Контроль — сервер полностью контролирует, какой переход возможен
  • Хронология — легко логировать действия
  • Не REST чистый — но часто более практичен

Недостатки:

  • Не совсем REST — по спецификации REST это должна быть операция над свойством, а не отдельный ресурс
  • Множество endpoints — для каждого действия нужен свой endpoint
  • Нелогичная иерархия — трудно документировать и выучить API

Вариант 4: POST с X-HTTP-Method-Override

Для клиентов, которые не поддерживают PATCH:

POST /api/v1/orders/123
X-HTTP-Method-Override: PATCH
Content-Type: application/json

{
  "status": "shipped"
}

Это хак, обычно не рекомендуется в новых API.

Вариант 5: State Machine / Workflow endpoints

Для сложных переходов состояний:

POST /api/v1/orders/123/transitions
Content-Type: application/json

{
  "to_status": "shipped",
  "reason": "Ready to dispatch"
}

Сервер может:

  • Проверить, возможен ли переход
  • Выполнить дополнительные действия
  • Залогировать переход
  • Отправить уведомления

Моя рекомендация в зависимости от ситуации

Используй PATCH, если:

  • Это простое изменение одного-двух полей
  • Не требуется дополнительная бизнес-логика
  • Клиентская часть может отправлять частичные обновления
  • API поддерживает JSON Merge Patch (RFC 7386) или JSON Patch (RFC 6902)

Используй PUT, если:

  • Требуется гарантировать, что отправляются все поля
  • Старая система, которая ожидает полный объект
  • Нужна максимальная идемпотентность
  • Клиент уже имеет полный объект и обновляет его

Используй POST к специальному endpoint, если:

  • Это сложное бизнес-действие (не просто изменение поля)
  • Требуется дополнительная логика (отправить письмо, запустить процесс)
  • Переход состояния имеет бизнес-правила
  • Нужно залогировать действие

Примеры из практики:

Пример 1: Заказ

# Изменить адрес доставки
PATCH /api/v1/orders/123
{"shipping_address": "..."}

# Отправить заказ (требует логики)
POST /api/v1/orders/123/ship
{"tracking_number": "..."}

# Отменить заказ (требует логики)
POST /api/v1/orders/123/cancel
{"reason": "..."}

Пример 2: Пользователь

# Обновить email
PATCH /api/v1/users/456
{"email": "newemail@example.com"}

# Деактивировать пользователя
POST /api/v1/users/456/deactivate

Пример 3: Документ

# Опубликовать документ
POST /api/v1/documents/789/publish

# Отправить на рецензию
POST /api/v1/documents/789/submit-for-review

Лучшая практика: REST Maturity Model

Ричард Филдинг (создатель REST) различает уровни зрелости API:

Уровень 3 (HATEOAS): API предоставляет ссылки на возможные действия:

{
  "id": 123,
  "status": "pending",
  "_links": {
    "self": {"href": "/api/v1/orders/123"},
    "ship": {"href": "/api/v1/orders/123/ship", "method": "POST"},
    "cancel": {"href": "/api/v1/orders/123/cancel", "method": "POST"}
  }
}

Клиент видит, какие действия доступны для текущего статуса.

Итоговая рекомендация

Для 80% случаев: используй PATCH для простых изменений полей и POST к специальным операциям для сложной бизнес-логики.

Это обеспечивает:

  • Ясность и предсказуемость
  • Гибкость для разных сценариев
  • Возможность добавить бизнес-логику в будущем
  • Удобство для клиента

Не зацикливайся на чистоте REST архитектуры — главное, чтобы API был понятен и удобен для использования.