Как правильно организовать обращение к внешнему REST сервису?
Добрый день!
У меня web-приложение (Java, Spring), который обрабатывает различные запросы от фронтенда по REST.
Есть необходимость при обработке некоторых запросов производить запрос дополнительной информации у внешних сервисов.
Приложение у меня работает по принципу CRM, т.е. за сложные запросы фронтенда создаются задачи, которые проходят различные стадии выполнения и потом пользователь получает уведомление о выполнении той или иной задачи.
У меня есть поток, который обрабатывает задачи, т.е. извлекает новую задачу, и проводит ее по разным стадиям выполнения.
Как правильно организовать данное взаимодействие чтобы не блокировать выполнение других задач пока данный потом будет делать обращение к внешнему REST сервису?
Была мысль сделать что-то типа обертки для работы с внешним сервисом, который будет работать в отдельном потоке и обрабатывать задачи с определенным состояние типа WAIT_FOR_EXTERNAL_DATA.
Т.е. когда задаче пришло время обратиться к внешнему сервису, то меняю ее состояние на WAIT_FOR_EXTERNAL_DATA, после чего основной поток обработки задач переходит к следующей задаче со статусом NEW, а данную задачу продолжает обрабатывать уже поток обертки сервиса - он формирует запрос к внешнему сервису, ждет ответа, после чего редактирует/обновляет данные задачи, меняет ее состояние на EXTERNAL_DATA_READY и дальше эта задача сможет продолжиться когда основной поток обработки задач будет брать новую задачу на выполнение (т.е. выбирать первую задачу из списка с определенным состоянием).
В правильном ли я направлении смотрю?
Как вариант воспользуйтесь ThreadPoolTaskExecutor и чекайте Future (для мониторинга выполнения задачи) в контроллере с помощью @ResponseBody по урлу (пример /task/{taskId}/check).
Здесь возможно несколько решений.
Прежде всего транщакционные решения. Это позволит сократить время без использования исключив сторонние Интеграции.
Использовать оркестрацию задачами интеграцией. Из самого простого вспоминается Quartz. Он позволяет работать в разных потоках и в рамках кластера.
В идеале стоит обратить внимание на реактивные фреймворки. В стеке Spring-а это Flume.
Очень давно использую и Vertx, очень похож на node.js и получил поддержку в Quarkus.