Как согласовать синхронный запрос от frontend к WebAPI и асинхронный от WebAPI к микросервисам, а потом вернуть ответ в frontend?
Не нашёл понятного мне паттерна реализации взаимодействия между компонентами микросервисной системы. В частности, примера, как реализовать связку между синхронным вызовом от клиента и его асинхронной обработкой. Поясню.
Есть приложение, построенное на микросервисах. Есть:
- фронтэнд (клиент на React, Vue, на чём угодно),
- публичный бэкэнд (WebAPI), обрабатывающий запросы от фронтэнда, + возможно какие-то дополнительные публичные микросервисы,
- набор внутренних микросервисов, принимающих запросы от бэкэнда через брокер сообщений (kafka, RabbitMQ, что угодно).
Если я правильно понял из множества статей в Сети, одна из популярных схем взаимодействия такая: запросы от фронтэнда в бэкенд (WebAPI, публичные сервисы первого уровня) синхронные, а запросы от WebAPI к внутренним микросервисам - асинхронные. Как-то так:
Фронтэнд даёт СИНХРОННЫЙ запрос в бэкэнд, и ждёт ответа. Запрос может быть типа асинхронным, т.е. с помощью Async AJAX, но по сути он всё равно держит коннект с сервером, потому что нужно сохранить канал, по которому вернётся ответ. Бэкэнд, получив запрос, отправляет его в асинхронную среду, а по факту - отправляет сообщение брокеру сообщений. В этот момент бэкэнд не имеет прямого коннекта с микросервисом-исполнителем, он просто должен подождать ответ от брокера. Но у него есть коннект с фронтэндом, по которому он отправит ответ, который он получит (или не получит никогда) от брокера. Т.е. бэкэнд должен держать коннект с фронтэндом, и при этом ждать ответ от брокера. Как это реализуется физически?
Тоже сейчас озадачен этим вопросом. Вы что-нибудь придумали в итоге? Я вижу 3 варианта:
1. Настроить вебсокет и связать фронт и бек тоже асинхронно
2. Если запрос может обрабатываться долго, то бекенд возвращает на фронт некий индектификатор, и фронт периодически обращается на бек, чтобы узнать, что там с его запросом.
3. Если запрос быстрый, то на беке просто обработать ответ (дождаться нужного события) и вернуть его на фронт.
Я думаю, первый вариант рабочий. Со вторым-третьим мне непонятно, как вы будете кодировать условие "если запрос быстрый"? Вы не можете всегда заранее знать, будет ли быстрым ответ: любой самый быстрый запрос потенциально может оказаться небыстрым (перегруз сети, ddos и пр.) Поэтому я думаю, что второй вариант можно использовать, но без предварительных условий.
Вообще, хотелось бы услышать от опытных людей про варианты и их плюсы-минусы...