Такие случаи обычно обрабатываются либо составной службой, расположенной между проблемами пользовательского интерфейса и выделенными службами. Эта композиционная служба ответит на запрос из пользовательского интерфейса, агрегирует данные из различных служб, чтобы построить модель полного представления, а затем отправит ее обратно в пользовательский интерфейс.
Эта служба может принимать различные формы и может быть либо композицией на стороне клиента, либо композицией на стороне сервера. Примером компоновки на стороне клиента является SPA, где компонент извлекает данные из нескольких API, проецирует данные во что-то полезное и отображает их, тогда как примером на стороне сервера может быть контроллер, обслуживающий представление. Я использовал термин «сервис» здесь свободно, но идея довольно общая.
Чтобы взглянуть на это иначе, удалите все понятия о размещенных API или даже знания о базах данных. Если бы вам пришлось интегрировать две разные библиотеки в код, как бы выглядела составная функция? Это будет называть одно, делать что-то, звонить во-вторых, делать что-то еще, возвращать результаты.
Размещенные API и т. Д. Просто добавляют детали реализации и сложности, но принцип остается прежним.
Вы высказали некоторые опасения по поводу влияния на производительность необходимости координировать несколько вызовов для разных служб, и это, безусловно, справедливо. Не только производительность, но и временная обработка ошибок и целостность транзакций становятся значительно более сложными при работе с вызовами API вместо объединения на уровне базы данных.
Некоторые вопросы, которые можно задать себе:
1. Насколько свежими должны быть мои данные? Можете ли вы принять кешированную версию пользователя и хотите ли вы сохранить и аннулировать этот кеш в вашем приложении?
2. Существуют ли оптимизированные для чтения версии API, которые уже выполняют некоторые преобразования данных для вас и поддерживают агрессивный кэш на их конце?
3. Правильно ли прорисованы мои границы вокруг компонентов или я должен объединить или разделить службы по-другому, чтобы данные, относящиеся друг к другу, находились достаточно близко, чтобы задержка не стала узким местом?
4. Существуют ли разные типы стратегий хранения данных, которые можно применять к тем компонентам, которые часто запрашиваются, чтобы они начали передавать изменения данных, что затем позволяет создавать собственные хранилища данных, оптимизированные для чтения (например, источник событий, pub-sub такого рода вещи)