Почему нужно использовать PATCH, а не POST для обновления ресурсов в REST API

Ответ

Использование PATCH вместо POST для обновлений следует принципам семантики HTTP и идемпотентности REST API.

Ключевые различия:

Аспект POST PATCH
Семантика Создание или комплексное действие Частичное обновление ресурса
Идемпотентность Нет (повторный запрос создаст дубли) Да (повторный запрос даст тот же результат)
Передаваемые данные Обычно весь ресурс Только изменяемые поля

Практический пример из моего опыта с JSON API:

// POST — для создания (не для обновления!)
POST /api/users
{
  "name": "Alice",
  "email": "alice@example.com",
  "role": "user"
}
// → Создаёт нового пользователя, возвращает 201 Created

// PATCH — для частичного обновления
PATCH /api/users/123
{
  "email": "new.alice@example.com"
}
// → Обновляет только email, возвращает 200 OK

// PUT — для полной замены (редко используется)
PUT /api/users/123
{
  "name": "Alice",
  "email": "new.alice@example.com",
  "role": "user"
}
// → Заменяет ВСЕ поля, null для отсутствующих

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

  1. Эффективность сети — передаются только изменяемые данные
  2. Безопасность — нельзя случайно затереть другие поля
  3. Поддержка конкурентности — можно использовать с ETag или If-Match
  4. Чёткая семантика — сразу понятно, что происходит частичное обновление

Реализация в Laravel:

// В контроллере
public function update(UserUpdateRequest $request, User $user)
{
    // PATCH-запрос автоматически обрабатывается
    $user->update($request->validated());
    return response()->json($user);
}

В микросервисной архитектуре мы строго соблюдали это различие, что упрощало интеграцию между сервисами.

Ответ 18+ 🔞

А, слушай, тут один чувак недавно пытался мне доказать, что для обновления данных можно POST везде пихать, мол, и так сойдёт. Я ему говорю — да ты что, ёпта, это же как на «Жигулях» в космос лететь! Разница между PATCH и POST — это не просто прихоть, а фундаментальная штука, про семантику HTTP и идемпотентность в REST API. Объясняю на пальцах, чтобы даже мартышлюшка поняла.

В чём, блядь, разница, если коротко:

Что сравниваем POST PATCH
Что делает Создаёт что-то новое или выполняет действие Только частично обновляет существующее
Идемпотентность Нет, блядь! Отправишь два раза — получишь два одинаковых ресурса, овердохуища дублей. Да! Отправишь хоть десять раз — результат будет один, как хуй с горы.
Что шлёшь Обычно всю эту простыню данных, весь объект. Только те поля, которые реально поменялись. Экономия трафика — просто волнение ебать!

Смотри, как это в коде выглядит, на живом примере:

// POST — это когда создаёшь с нуля, ёбана!
POST /api/users
{
  "name": "Василий",
  "email": "vasya@example.com",
  "role": "user"
}
// → Бах! Новый пользователь в базе. Статус 201 Created.

// PATCH — это когда у Василия почту поменять надо.
PATCH /api/users/123
{
  "email": "noviy.vasya@example.com"
}
// → Щёлк! Обновил только почту. Остальное как было. Статус 200 OK.

// PUT — это редкостный зверь, полная замена. Опасно, как вилкой в глаз.
PUT /api/users/123
{
  "name": "Василий",
  "email": "noviy.vasya@example.com",
  "role": "user"
}
// → Всё, что не указал — станет null. Пиздец, а не метод.

А теперь, почему PATCH — это охуенно:

  1. Не жрёт трафик попусту. Зачем гонять все поля, если поменялся один email? Это же ядрёна вошь!
  2. Безопаснее. Не получится случайно, по пьяни, затереть поле role до null, потому что его в запросе просто не было. Доверия ебать ноль к клиентам, лучше перестраховаться.
  3. Для конкурентности подходит. Можно прикрутить ETag и проверять, не менял ли кто ресурс, пока ты думал.
  4. Семантика кристальная. Увидел в логах PATCH /api/users/123 — сразу понятно, что тут частичное обновление, а не какая-то хитрая жопа.

В Laravel это вообще делается в одну строку:

public function update(UserUpdateRequest $request, User $user)
{
    // Фреймворк сам разберётся, PATCH там или PUT.
    $user->update($request->validated()); // Обновляем только то, что пришло.
    return response()->json($user);
}

Раньше, на одном проекте с кучей микросервисов, мы забили хуй на эти правила и везде POST юзали. Потом, когда сервисы начали друг другу «апдейты» слать, начался такой пиздец, такой пиздец... Одни дубли создавали, другие поля затирали. Сам от себя охуел, когда разбирался. Как только перешли на чёткое разделение (POST для создания, PATCH для обновления) — жить стало проще, интеграции перестали сыпаться каждую неделю. Так что не будь, прости господи, полупидором, используй методы по назначению.