Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
PATCH метод в REST
PATCH — это HTTP метод для частичного обновления ресурса. Он отличается от PUT тем, что обновляет только те поля, которые были отправлены в запросе, без замены всего ресурса.
PATCH vs PUT
Основное различие:
PUT — полная замена ресурса. Если не отправить все поля, отсутствующие поля станут null или удалены.
// PUT запрос
PUT /api/users/123
{
"name": "John"
}
// Результат: все другие поля удаляются/обнуляются
// User становится {id: 123, name: "John", email: null, age: null}
PATCH — частичное обновление. Обновляются только отправленные поля, остальное сохраняется.
// PATCH запрос
PATCH /api/users/123
{
"name": "John"
}
// Результат: обновляется только name, остальные поля не меняются
// User остаётся {id: 123, name: "John", email: "old@email.com", age: 30}
Практический пример
Представим сущность User:
@Entity
@Table(name = "users")
public class User {
@Id
private Long id;
private String name;
private String email;
private String phone;
private LocalDate birthDate;
private String city;
}
PUT — полная замена
@PutMapping("/{id}")
public ResponseEntity<User> updateUserFull(
@PathVariable Long id,
@RequestBody User updatedUser) {
User user = userRepository.findById(id)
.orElseThrow(() -> new NotFoundException("User not found"));
// ПОЛНОЕ ПЕРЕЗАПИСЫВАНИЕ
user.setName(updatedUser.getName());
user.setEmail(updatedUser.getEmail());
user.setPhone(updatedUser.getPhone());
user.setBirthDate(updatedUser.getBirthDate());
user.setCity(updatedUser.getCity());
User saved = userRepository.save(user);
return ResponseEntity.ok(saved);
}
PATCH — частичное обновление
@PatchMapping("/{id}")
public ResponseEntity<User> updateUserPartial(
@PathVariable Long id,
@RequestBody Map<String, Object> updates) {
User user = userRepository.findById(id)
.orElseThrow(() -> new NotFoundException("User not found"));
// Обновляем ТОЛЬКО присутствующие поля
updates.forEach((key, value) -> {
switch(key) {
case "name" -> user.setName((String) value);
case "email" -> user.setEmail((String) value);
case "phone" -> user.setPhone((String) value);
case "birthDate" -> user.setBirthDate(
LocalDate.parse((String) value));
case "city" -> user.setCity((String) value);
}
});
User saved = userRepository.save(user);
return ResponseEntity.ok(saved);
}
Лучше — использование DTO с nullable полями
public class UserUpdateDto {
@Nullable
private String name;
@Nullable
private String email;
@Nullable
private String phone;
}
@PatchMapping("/{id}")
public ResponseEntity<User> updateUserPartial(
@PathVariable Long id,
@RequestBody UserUpdateDto updateDto) {
User user = userRepository.findById(id)
.orElseThrow(() -> new NotFoundException("User not found"));
if (updateDto.getName() != null) {
user.setName(updateDto.getName());
}
if (updateDto.getEmail() != null) {
user.setEmail(updateDto.getEmail());
}
if (updateDto.getPhone() != null) {
user.setPhone(updateDto.getPhone());
}
return ResponseEntity.ok(userRepository.save(user));
}
Или с JSON Patch (RFC 6902)
Для сложных операций используется стандартный JSON Patch формат:
// Запрос
PATCH /api/users/123
Content-Type: application/json-patch+json
[
{"op": "replace", "path": "/name", "value": "John Doe"},
{"op": "replace", "path": "/email", "value": "john@example.com"},
{"op": "add", "path": "/phone", "value": "+1234567890"}
]
Реализация с JsonPatch (spring-boot-starter-json):
@PatchMapping("/{id}")
public ResponseEntity<User> updateUserWithJsonPatch(
@PathVariable Long id,
@RequestBody JsonNode patchNode) throws JsonPatchException {
User user = userRepository.findById(id)
.orElseThrow(() -> new NotFoundException("User not found"));
JsonPatch patch = JsonPatch.fromJson(patchNode);
ObjectMapper mapper = new ObjectMapper();
JsonNode patched = patch.apply(
mapper.convertValue(user, JsonNode.class));
User updated = mapper.treeToValue(patched, User.class);
return ResponseEntity.ok(userRepository.save(updated));
}
Когда использовать PATCH
- Частичные обновления — когда клиент обновляет только несколько полей
- Экономия трафика — отправляется только изменённые данные
- Снижение вероятности ошибок — не нужно отправлять все поля
- Batch операции — обновление списка элементов с небольшими изменениями
Когда использовать PUT
- Полная замена ресурса — когда нужно перезаписать весь объект
- Идемпотентность — PUT гарантирует, что повторные запросы дают одинаковый результат
- Создание ресурса — PUT может использоваться для создания с известным ID
Статус коды
- 200 OK — обновление успешно, возвращаем обновленный ресурс
- 204 No Content — обновление успешно, тело ответа не требуется
- 400 Bad Request — неверные данные в запросе
- 404 Not Found — ресурс не найден
- 409 Conflict — конфликт версий (оптимистичная блокировка)
PATCH — это современный и эффективный способ частичного обновления ресурсов в REST API.