Много асинхронных вызовов против одного вызова API

12

Мы разрабатываем REST API, который, помимо прочего, будет использоваться веб-интерфейсом HTML5 через javascript. Приложение предназначено для использования в организации и обычно имеет около 300 пользователей, но мы хотим масштабировать до 1000 пользователей или около того.

Обычно соединения с API будут осуществляться в локальной сети, поэтому качество и задержка соединения будут хорошими, хотя не исключено случайное использование через Интернет, где соединения могут быть медленнее и с большим запаздыванием через 3G / 4G.

Два варианта, которые мы подумали:

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

    • Плюсы: простота.
    • Минусы: Больше подключений к серверу.
  2. Контроллер внешнего интерфейса выполнит один вызов API, передавая в качестве параметров объекты, которые необходимо получить.

    • Плюсы: только одно подключение к серверу, хотя сервер сделает несколько подключений к базе данных.
    • Минусы: требуются механизмы как в интерфейсе, так и в API. Это усложняет дизайн.

Дополнительные пояснения: будут разные ресурсы ... / Product ... / Locations и т. Д. Эти ресурсы могут быть получены отдельно, но будет другой абстрактный ресурс ... / screen? Product & Locations, который будет извлекать оба за один вызов.

mattinsalto
источник

Ответы:

14

Вариант 1 (несколько асинхронных вызовов) является лучшим выбором, потому что:

  1. каждый отдельный вызов - это отдельная сущность , поэтому вы можете повторить попытку индивидуально, если что-то не получится. В монолитной архитектуре «одного звонка», если что-то не получается, вы должны сделать весь вызов снова
  2. код на стороне сервера будет проще: опять же, модульность , а это означает, что разные разработчики могут работать на разных ресурсах API
  3. В типичном шаблоне MVC не имеет смысла, чтобы один вызов API загружал несколько отдельных ресурсов ; Например, если вы делаете запрос на /productsполучение списка продуктов для отображения на странице, а также хотите отобразить список мест, где продаются популярные продукты, у вас есть два отдельных ресурса: Productи Location. Хотя они отображаются на одной и той же странице, вы не можете логически сделать вызов /productsи заставить его также возвращать местоположения
  4. Ваши отчеты о регистрации / использовании будут проще в модульном подходе. Если вы делаете запрос /productsи загружаете местоположения, ваши файлы журналов будут очень запутанными
  5. если у вас есть проблема с конкретным ресурсом, подход с одним вызовом приведет к разрыву всей страницы, и вашим пользователям не будет понятно, что сломалось - и это означает, что вашей команде потребуется больше времени, чтобы решить проблему; однако в модульном подходе, если что-то сломается, будет очень очевидно, что сломалось, и вы можете исправить это быстрее. Это также не разрушит остальную часть страницы (если вещи не слишком тесно связаны ...)
  6. в целом, будет легче вносить изменения, если вещи разделены; если у вас есть 5 ресурсов, загружаемых одним вызовом API, будет сложнее понять, как не сломать вещи, когда вы хотите что-то изменить

Все дело в том, что ресурсы являются отдельными, и в REST API возвращение множества отдельных ресурсов из одного пути API не имеет смысла, даже если вы «сохраняете соединения с сервером». Кстати, использование параметров для условной загрузки (разных) ресурсов не является RESTful.

Все это говорит о том, что единственная логическая опция - сделать несколько асинхронных запросов для разделения ресурсов: используйте модульный подход !

PS - Не оптимизируйте преждевременно «соединения с сервером», особенно когда HTTP-соединения невероятно низки и вы находитесь в локальной сети. Такое мышление вместо выбора более простого дизайна сразу же приведет к неприятностям позже.

Крис Сирефице
источник
1
Кроме того, модульные, вероятно, проще для модульного тестирования.
user949300
@ user949300 Хорошо, я даже не думал об этом! Модульное тестирование на самом деле было бы намного проще, если бы все было развязано.
Крис Cirefice
Спасибо за быстрый и расширенный ответ. Я согласен на все, но я думаю, что я не объяснил это хорошо. Будут разные ресурсы / Продукт / Местоположения и т. Д. Эти ресурсы могут быть получены отдельно, но будет другой абстрактный ресурс / экран - Продукт и Местоположения, которые будут извлекать оба за один вызов. Во всяком случае, я также предпочитаю более простой способ.
Mattinsalto
@mattinsalto Подход /screen?Product&Locations- плохой подход, по крайней мере со всем моим опытом разработки REST API и веб-приложения, которое их использует. С чисто монолитной точки зрения (например, в Ruby on Rails) наличие маршрута, /screenкоторый загружает Productи Locationресурсы, и все в порядке. Однако, с точки зрения REST , вы никогда не захотите, чтобы маршрут загружал более одной (если вы не присоединяетесь к таблицам, чтобы получить больше данных одновременно). Что /screenнужно сделать , это загрузить основную страницу макета и вы AJAX вашего API для получения данных ( Product, Locationи т.д.).
Крис Cirefice
@mattinsalto Если вы разрабатываете REST API для использования в веб-приложении (а также в других целях), вам нужно просто сосредоточиться на данных , а не на том, как ваши приложения будут использовать эти данные. API REST должен поддерживать базовые операции (по мере необходимости) для каждого ресурса. Затем ваше веб-приложение выполнит загрузку всех ресурсов, необходимых для любой страницы (например, /screenбудет AJAX HTTP GETдля /products/popularи /locations). Ваш API не должен быть тем, который выполняет несколько загрузок, потому что маловероятно, что вы будете отображать данные таким же образом в веб-приложении против Android, например.
Крис Cirefice