API для отдыха - мобильные вызовы

25

Я работаю над новым проектом iOS-приложения для мобильных устройств. Происходят некоторые изменения в архитектуре, и оказывается, что нам придется полагаться на собственный частный API, который будет использоваться приложением, которое мы создаем, а также другими клиентами, такими как веб-сайт.

Разрабатываемый API соответствует стилю Rest ресурсо-ориентированных операций URI и CRUD, сопоставленных с глаголами HTTP. вещи как:

GET www.example.com/books
DELETE www.example.com/books/482094
POST www.example.com/users/6793

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

Мобильные клиенты имеют серьезные ограничения, когда дело доходит до подключения, и в идеале мы должны следовать такому правилу:

1 экран == 1 вызов API

1 сохранить == 1 вызов API.

Есть много ситуаций, когда это приводит вас к столкновению с принципами проектирования REST, например:

  • скажем, ваше приложение было в автономном режиме в течение дня, и вам нужно синхронизировать с четырьмя таблицами серверных баз данных, и вам нужен вызов, как www.example.com/sync_everything?since=2015-07-24
  • Допустим, есть экран, где пользователь может редактировать многие из своих объектов, например, отмечая галочкой задачи в своем списке задач. должен быть способ отредактировать все эти записи задач в одном пакетном вызове API, а не один вызов API на редактирование.
  • скажем, есть экран, который смешивает информацию из таблиц БД ORDER, SALESMEN и PRODUCT, я должен получить эти данные за один вызов вместо трех.

риск состоит в том, что мы можем получить самый API-интерфейс Restful, а также самое бесполезное мобильное приложение без ответа.

Дело в том, что я всего лишь новый подрядчик, и мне нужно что-то, что поможет мне сделать эти выводы, некоторые статьи из уважаемых источников или что-то в этом роде. Основные игроки, которые идут на компромисс со стилем REST для своего мобильного клиента (например, с помощью составных совокупных конечных точек API).

Или любое решение для этой общей проблемы. Благодарность!

MikaelW
источник
3
Возможно, ваш вопрос звучит так: «Как API может доставлять коллекции объектов и встроенных объектов одинакового или разного типа, сохраняя стиль REST?» Я понимаю ваш вопрос?
Joshp
Я считаю, что общий ответ заключается в том, что каждый вызов REST должен принимать различные необязательные параметры, поэтому он может быть гибким, но все же относительно интуитивно понятным. Случай синхронизации всегда будет сложным, но для обычных страниц вы обычно просматриваете несколько вызовов одного типа , то есть все GET, верно?
Ixrec
1
Я думаю, что адаптация вашего API - это неправильное решение, когда проблема заключается в отсутствии параллельных запросов - 8 небольших запросов не намного хуже, чем один большой запрос, когда им не нужно ждать друг друга. Вы можете переключиться на HTTP / 2? Или хотя бы использовать конвейер HTTP / 1.1?
Амон
Смотрите также: Шаблоны для обработки пакетных операций в веб-сервисах REST? , Ключ идентифицирует, какие виды команд (и при каких предварительных условиях) могут быть объединены вместе без конфликтов, а затем создает представление JSON для пакетного заказа, а затем отправляет его. Он теряет основную привлекательность для REST, а именно кешируемость, но кешируемость не всегда актуальна для всех видов приложений. Обратите внимание, что пакет / параллелизм не применим, если есть логические зависимости.
Rwong
Аналогия для ситуации, когда посреднику необходимо выполнить несколько операций в последовательности с нетривиальными логическими зависимостями от каждой предыдущей операции, представляет собой нечто вроде «хранимой процедуры», которая выполняется в этом посреднике, а не внутри базы данных. Ниже посреднику разрешено преобразовывать один вызов «хранимой процедуры» в столько запросов RESTful, сколько необходимо, но это деталь реализации посредника.
Руонг

Ответы:

27

Разрабатываемый API соответствует стилю Rest ресурсо-ориентированных операций URI и CRUD, сопоставленных с глаголами HTTP.

Это ваша проблема прямо здесь.

Вы ограничили свои ресурсы (я предполагаю) моделями в вашей базе данных. Таким образом, загрузка всех этих ресурсов занимает много времени, потому что ваш сервер не имеет понятия о ресурсах, которые не представлены в базе данных.

Например, может иметь

www.example.com/books/482094
www.example.com/books/582045
www.example.com/books/427454
www.example.com/books/319343

что все должно быть загружено, чтобы получить мою библиотеку

Это не проблема с дизайном RESTful, это настоящий анти-шаблон REST. В REST абсолютно ничего не говорится о том, что наши ресурсы должны иметь взаимно однозначное сопоставление с чем-либо еще в вашей системе, включая модели баз данных.

Решение состоит в том, чтобы создать больше ресурсов, которые лучше соответствуют тому, что вы хотите загрузить. Если у вас есть 5 ресурсов, которые всегда заканчиваются вместе, создайте новый ресурс, который содержит информацию для этих 5 ресурсов.

То, что вы должны иметь, это что-то вроде этого

www.example.com/users/334/my_library

который просто загружает все книги для этого пользователя. my_library не является моделью в вашей базе данных, но это ресурс. Сервер создает его на основе моделей в базе данных, но нет сопоставления «один к одному», и сервер может создавать этот ресурс без изменения модели БД.

Вы также можете иметь

www.example.com/users/334/favioured_books
www.example.com/users/334/books_ordered_last_week
www.example.com/users/334/wishlist

ни одна из которых не должна существовать как модель в вашей базе данных или доменном пространстве.

Широко распространено заблуждение, что это неправильная вещь, потому что фреймворки, подобные Rails, учили людей отображать ресурсы способом 1-к-1 для моделей в доменном пространстве, которые снова отображают 1-к-1 со строками базы данных. Это не обязательно и не рекомендуется.

Ресурсы должны быть многочисленными, дешевыми и легкими . Их должно быть легко создать, и они должны быть абстрагированы от вашей доменной модели. Если вы обнаружите, что вам нужен новый, просто создайте новый. Если у вас есть проблемы с этим, то это ошибка вашего фреймворка, а не ошибка REST.

Теперь большое предостережение в том, что ваша инфраструктура позволяет вам это делать. Такие фреймворки, как Rails и Django, которые взяли курс на карту 1-к-1, чтобы «сэкономить ваше время», затрудняют это. Но это недостаток фреймворков, а не дизайна RESTful.

Вот Джим Уэббер, обсуждающий это более подробно (включая несколько раскопок в Rails!)

https://yow.eventer.com/yow-2011-1004/domain-driven-design-for-restful-systems-by-jim-webber-1047

Кормак Мулхолл
источник
Это очень интересно, и я полностью согласен с этим, но, к сожалению, я не тот, кто делает API, и у меня мало способов повлиять на это, если таковые имеются. Многие люди будут использовать этот «анти-паттерн» повсеместно (по многим причинам, с ограничениями фреймворка), и они просто используют определение URI для четкого осмысления своей базы данных. Конечные точки API - это просто еще один способ визуализации своей БД ... Кроме того, в некоторых случаях создание ресурса, подобного тому, который вы описали, затруднено из-за того, что объекты действительно отличаются, просто присвоение им имен приведет к очень туманным терминам.
MikaelW
Чтобы вернуться к вопросу с точки зрения эффективности, они согласились с тем, что если мобильный экран очень медленный (и только если это произошло), возможны некоторые составные вызовы, но они будут находиться в компоненте, который оборачивается вокруг API ( а не сам API), будут использоваться только мобильными клиентами и не будут рассматриваться как часть основного API, основного домена.
MikaelW
@MikaelW, ты прав. Даже то, что сказал Кормак, является идеальным сценарием, иногда вы работаете с API, который должен обслуживать множество других систем (настольные, мобильные, веб, запланированные задания, устаревшие системы и т. Д.). Этот вид API должен быть действительно гибким, предоставляя ресурсы для максимально возможного использования различных возможностей, но не может удовлетворить все конкретные требования производительности от одного потребителя. В этом случае у вас не так много вариантов ...
Дерик,