Что делает HTTP-метод PATCH в REST API?

Ответ

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

Ключевые отличия от PUT:

  • PUT: Идемпотентный. Клиент отправляет полное представление ресурса. Сервер полностью заменяет ресурс предоставленными данными.
  • PATCH: Не обязательно идемпотентный (зависит от формата запроса). Клиент отправляет инструкции ("патч") для модификации ресурса.

Практический пример (ASP.NET Core с JSON Patch):

  1. Запрос клиента:

    PATCH /api/users/123 HTTP/1.1
    Content-Type: application/json-patch+json
    
    [
      { "op": "replace", "path": "/name", "value": "Alice" },
      { "op": "add", "path": "/tags", "value": ["new", "user"] }
    ]
  2. Обработка на сервере:

    [HttpPatch("{id}")]
    public IActionResult PatchUser(int id, [FromBody] JsonPatchDocument<User> patchDoc)
    {
        var user = _userRepository.GetById(id);
        if (user == null)
            return NotFound();
    
        patchDoc.ApplyTo(user); // Применяем изменения к объекту
        _userRepository.Update(user); // Сохраняем в БД
    
        return NoContent(); // 204 No Content
    }

Форматы PATCH-запросов: Стандарт не диктует конкретный формат. Наиболее распространен JSON Patch (RFC 6902, как в примере выше). Также используется JSON Merge Patch (RFC 7396) или собственные форматы.

Когда использовать PATCH:

  • Для обновления больших ресурсов, где передача всего объекта неэффективна.
  • Когда нужно отправить только измененные поля.
  • Для реализации сложных операций обновления (например, перемещения элемента в списке).

Ответ 18+ 🔞

Смотри, есть такая штука — PATCH. Это когда тебе не надо переписывать весь документ с нуля, а только поправить пару строчек. В отличие от этого тупорылого PUT, который требует отправить всё целиком, даже если поменял одну запятую.

Ключевая разница, если по-простому:

  • PUT: Это как сказать — «выкинь всю старую хрень и положи вот эту новую». Идемпотентно, да. Но если забыл хоть одно поле — оно на сервере обнулится, и ты потом охуеешь.
  • PATCH: Это как дать инструкцию — «слушай, в третьем абзаце замени „хорошо“ на „охуенно“, и в конец добавь смайлик». Не всегда идемпотентно, но зато экономно.

Пример на ASP.NET Core (с JSON Patch):

  1. Что шлёт клиент:

    PATCH /api/users/123 HTTP/1.1
    Content-Type: application/json-patch+json
    
    [
      { "op": "replace", "path": "/name", "value": "Alice" },
      { "op": "add", "path": "/tags", "value": ["new", "user"] }
    ]

    Типа, «замени имя на 'Alice' и добавь пару тегов».

  2. Как это жуёт сервер:

    [HttpPatch("{id}")]
    public IActionResult PatchUser(int id, [FromBody] JsonPatchDocument<User> patchDoc)
    {
        var user = _userRepository.GetById(id);
        if (user == null)
            return NotFound(); // Нету такого — иди нахуй
    
        patchDoc.ApplyTo(user); // Накладываем патч на объект
        _userRepository.Update(user); // Пишем в базу
    
        return NoContent(); // Всё ок, 204, без лишних телодвижений
    }

Про форматы этих патчей: Стандарт сам по себе — просто идея. Конкретный формат — это уже твои проблемы. Чаще всего используют JSON Patch (как в примере, RFC 6902). Есть ещё JSON Merge Patch, но он для простых случаев. А вообще можно хоть в XML, хоть двоичный протокол придумать — лишь бы сервер и клиент понимали друг друга.

Когда это реально нужно:

  • Обновляешь здоровенную сущность, а поменял одно поле — зачем весь этот воз тащить по сети?
  • Хочешь сделать атомарное обновление сразу нескольких полей в одном запросе.
  • Реализуешь какую-нибудь хитрожопую логику, типа «перемести этот элемент из списка A в список B». Через PUT это пиздец как неудобно.