В чем разница между HTTP-методами PATCH и PUT?

Ответ

Основное различие между PUT и PATCH заключается в способе обновления ресурса на сервере.


  • PUT — это идемпотентный метод, который используется для полной замены ресурса. Вы должны отправить в теле запроса все поля ресурса. Если ресурс не существует, PUT может его создать.



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


Пример на Go для PATCH

Для корректной обработки частичных обновлений в Go часто используют указатели в структуре. Это позволяет отличить поле, которое не было передано (nil), от поля, которому было передано нулевое значение (например, пустая строка "").

// Структура для частичного обновления пользователя
type UpdateUserPayload struct {
    Name  *string `json:"name,omitempty"`
    Email *string `json:"email,omitempty"`
}

// currentUser - существующий ресурс, который мы обновляем
var currentUser = User{ID: 1, Name: "Admin", Email: "admin@example.com"}

func updateUser(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPatch {
        http.Error(w, "Метод не разрешен", http.StatusMethodNotAllowed)
        return
    }

    var payload UpdateUserPayload
    if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    // Применяем обновления, только если поля были переданы в JSON
    if payload.Name != nil {
        currentUser.Name = *payload.Name
    }
    if payload.Email != nil {
        currentUser.Email = *payload.Email
    }

    // ... логика сохранения в БД ...

    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(currentUser)
}

Ключевые моменты:

  • Идемпотентность: PUT идемпотентен (повторные запросы с одинаковыми данными дают тот же результат), а PATCH — нет (два одинаковых PATCH запроса могут привести к разным результатам, если они, например, инкрементируют значение).
  • Пропускная способность: PATCH экономит трафик, так как передает только измененные данные.
  • Форматы: Для PATCH часто используют Content-Type: application/merge-patch+json (для простого слияния) или application/json-patch+json (для более сложных операций, описанных в RFC 6902).