Система запускает операцию, которая может длиться минуты. Какой паттерн API позволит не удерживать клиентское соединение до завершения?
Нужно использовать асинхронный паттерн длительной операции: API быстро принимает запрос, создает ресурс операции с уникальным идентификатором и возвращает его клиенту. Клиент затем проверяет состояние операции через отдельный ресурс либо получает уведомление о завершении.
Такой подход отделяет прием команды от ее выполнения и не связывает жизненный цикл операции с одним сетевым соединением.
Классическая модель HTTP предполагает запрос и ответ в рамках одной операции. Она удобна для быстрых действий, но плохо подходит для обработки файлов, массовых расчетов, интеграций с медленными внешними системами и других задач с неопределенной длительностью.
В распределенных системах сетевые соединения могут закрываться по тайм-ауту, балансировщики могут ограничивать время ожидания, а клиент может временно потерять связь. Поэтому длительные операции стали моделировать как самостоятельные управляемые ресурсы.
Если клиент ждет завершения операции в одном соединении, он может получить тайм-аут, хотя сервер продолжит работу. Повторная отправка запроса после такого тайм-аута способна запустить вторую операцию, если отдельно не определены правила повторов и идентификации.
Синхронная схема также удерживает ресурсы сервера, усложняет масштабирование и не дает клиенту надежного способа отличить состояние выполняющейся операции от потери ответа.
При получении команды сервер должен быстро подтвердить, что запрос принят, создать ресурс операции и присвоить ему идентификатор. В ответе передаются начальный статус, например выполняется, и ссылка или иной адрес для получения состояния.
Ресурс операции обычно содержит статус, время создания, время завершения, результат либо ссылку на результат, а при ошибке — нормализованное описание причины. Набор состояний должен быть конечным и однозначным: например, выполняется, успешно завершена, завершена с ошибкой, отменена.
Клиент может опрашивать ресурс с увеличивающимся интервалом или подписаться на уведомление. При опросе важно определить срок хранения ресурса операции, правила ответа после его удаления и предельную частоту запросов.
Для отмены требуется отдельная явно поддержанная операция. Отправка запроса на отмену не всегда означает немедленную остановку: задача может уже перейти в необратимую фазу, поэтому API должен различать запрос на отмену и фактический статус отмененной операции.
Нужно отдельно решить вопрос повторной отправки команды. Идентификатор операции должен быть связан с исходным запросом так, чтобы повторная доставка не создавала неожиданно несколько независимых работ. Это не следует считать автоматически решенным только потому, что выполнение асинхронное.
Асинхронность повышает сложность: клиенту нужны состояния и обработка ошибок, результат может быть временно недоступен, а согласованность между созданием операции и запуском фоновой обработки требует надежного механизма передачи задания. Компромисс оправдан, когда длительность или надежность выполнения важнее простоты немедленного ответа.
Сервис принимает архив документов на проверку, а обработка занимает от нескольких секунд до нескольких минут. Рассматривались три варианта: держать соединение открытым до результата, сразу возвращать результат и выполнять проверку позже без наблюдаемого статуса, либо создать ресурс операции.
Первый вариант прост для клиента, но подвержен тайм-аутам и расходует соединения. Второй снижает требования к API, однако клиент не понимает, завершилась ли проверка, и не может корректно получить результат или причину ошибки.
Выбран третий вариант: после приема архива создается операция со статусом выполняется, а результат становится доступен после перехода в состояние успешно завершена. Для клиентов с поддержкой уведомлений добавили callback, но ресурс операции оставили источником состояния, потому что уведомление могло потеряться.
В результате соединения не удерживались во время проверки, клиент получил единый способ отслеживать прогресс и ошибки, а повторное получение статуса не запускало обработку заново.
Ответ: Нет. Идентификатор без описанного ресурса состояния не определяет, где и как узнать результат, какие статусы допустимы, когда задача считается завершенной и как трактовать ошибку. Контракт должен описывать жизненный цикл операции, формат результата, срок доступности данных и поведение для неизвестного или уже удаленного идентификатора.
Ответ: Уведомление может не дойти из-за сетевой ошибки, временной недоступности получателя или сбоя при его обработке. Поэтому уведомление лучше рассматривать как ускоритель доставки, а не как единственный источник истины. Клиент должен иметь возможность безопасно запросить текущее состояние операции повторно.
Ответ: В модели операции должны быть явно разделены повторяемые и окончательные состояния. Временная ошибка допускает автоматический повтор по правилам сервиса, а окончательная ошибка требует изменения входных данных или вмешательства пользователя. Если API не различает эти случаи, клиент либо будет бесконечно повторять безнадежную задачу, либо преждевременно сообщит о неуспехе там, где операция могла завершиться после повторной обработки.