Sobes.tech
Назад к вопросам
Senior
6

Какие правила идемпотентности есть для HTTP-методов? Как решить проблему дублирования POST-запросов?

Компании, где спрашивали
СБЕРСБЕР

Ответ от нейросети

sobes.tech AI

В HTTP методы имеют следующие правила идемпотентности:

  • GET, PUT, DELETE, HEAD, OPTIONS, TRACE — идемпотентны. Это значит, что повторный запрос с теми же параметрами не изменит состояние сервера дополнительно.
  • POST — не идемпотентен, так как повторный запрос может создавать дубликаты или изменять состояние несколько раз.

Проблема дублирования POST-запросов возникает, например, при повторной отправке формы из-за ошибки сети или повторного нажатия кнопки.

Решения:

  1. Использование уникальных идентификаторов (идемпотентных ключей)

    • Клиент генерирует уникальный requestId для каждого POST.
    • Сервер сохраняет обработанные requestId и игнорирует повторные запросы с тем же ID.
  2. Post/Redirect/Get (PRG) паттерн

    • После успешного POST сервер делает редирект на GET.
    • Повторное обновление страницы не повторит POST.
  3. Использование токенов CSRF или одноразовых токенов

    • Токен становится недействительным после первого использования.
  4. Обработка на уровне базы данных

    • Использование уникальных ограничений, транзакций и проверок для предотвращения дублирования.

Пример с уникальным requestId:

@PostMapping("/submit")
public ResponseEntity<?> submit(@RequestBody Data data, @RequestHeader("X-Request-ID") String requestId) {
    if (requestRepository.existsByRequestId(requestId)) {
        return ResponseEntity.status(HttpStatus.CONFLICT).body("Duplicate request");
    }
    // обработка запроса
    requestRepository.save(new RequestEntity(requestId));
    return ResponseEntity.ok().build();
}