Меня зовут Андрей Буйновский, я разработчик в ИТ-компании. Мы с командой решили написать эту статью и поделиться некоторыми проблемами, подводными камнями и их решениями в разработке мобильного приложения для одного нашего заказчика из ритейла. 

Мы разработали интернет-магазин для крупной торговой сети. После запуска интернет-магазина, мы перешли к развитию проекта, в рамках которого появилась задача по созданию дополнительного канала по взаимодействию с покупателями. Вопрос о выборе API для бэкэнда не стоял, так как интернет-магазин был разработан на платформе 1С-Битрикс, система имеет необходимый функционал для работы с альтернативным фронтом и мобильным приложением. Перед нашей командой стояла задача разработать мобильное приложение на основе Bitrix REST API для платформ iOS и Android с сохранением функционала действующего интернет-магазин заказчика. Это означало необходимость использования компонентов, уже реализованных для интернет-магазина, копирования их с целью сохранения логики, удаления верстки и использования возвращаемых данных.

В ходе разработки мы столкнулись со следующими проблемами, некоторые из них мы сами себе создали:

  • строгая типизация данных на мобильных платформах Ios и андроид,

  • распределение моделей для их максимального переиспользования,

  • не разделили данные на несколько методов (влияет на скорость загрузки),

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

  • не использовали скелетон,

  • при большом объеме данных компонент не кэшировался,

  • не использовали разделение сессий и не блокирующую сессию, при использовании memcached.

Перед нашей командой разработки была поставлена задача: все функциональные возможности, реализованные в интернет-магазине, должны быть доступны и в мобильном приложении. Для этого мы воспользовались модулем fact.api (разработанным в нашей компании), используя его технические методы, например, для формирования и проверки токенов. Однако для всех аспектов, связанных с получением и передачей данных, нам пришлось разрабатывать собственные методы.

Мы брали компоненты интернет-магазина вставляли их в методы и из них получали данные при помощи ob_start(); $str = ob_get_contents(); ob_end_clean();

Но изначально при разработке мы не учли момент с правильным именованием ключей в массивах и созданием общих моделей для одного типа информации в разных местах приложения, делали как будто для «NUXT». После подключения мобильных разработчиков мы поняли, что у нас проблемы с типизацией данных, потому как им в одном и том же поле приходила string или int, из-за чего мобильное приложение падало.

Когда начали в result_modifier.php типизировать данные, и, вроде бы, все начало получаться, столкнулись со следующей бедой: json_encode и json_decode после преобразования меняет сам тип данных, например мы id передаем как string, а на выходе получаем int. Для того чтобы такое не происходило, нужно следить чтоб в json_encode не было ключа JSON_NUMERIC_CHECK. Тогда тип данных не будет меняться при декодировании.

Следующая проблема была в том, что если в массиве ключи идут ассоциативные (не 0,1,2), то тогда тип данных будет объект, и когда массив будет пустым, то стоит его типизировать в объект, чтобы не сломалось приложение.

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

Стоит использовать принципы SOLID, то есть максимально при отдаче данных распределить на как можно больше методов, потому что мобильное приложение может тянуть их асинхронно, и тогда приложение будет работать быстрее. Например, для главной страницы приложения может быть огромное количество данных, но пользователь увидит сразу только 25%, а остальное можно подгрузить позже. 

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

Не стоит перегружать метод json лишними данными. Те данные, которые не нужны при выводе, но компонент их отдает, стоит вырезать, тем самым уменьшив размер страницы отдаваемой сервером. 

В ходе отладки приложения заметили, что некоторые запросы обрабатываются очень долго, но при этом трудоемких процессов там не было. При погружении в проблему поняли, что у нас происходит блокировка запросов, и они выстраиваются в очередь. Решили эту проблему путем разделения сессий на неблокирующую. Если мы уверены, что наш запрос не будет вносить никаких изменений, а нужен лишь для получения данных, то там ставим параметр define('BX_SECURITY_SESSION_READONLY', true);, и запрос не блокируется.

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

Дополнительно необходимо внедрить механизм логирования на стороне мобильного приложения в процессе разработки, поскольку такие логи часто являются важными. Например, требуется регистрировать в логах на стороне мобильного приложения информацию о данных, полученных с сервера, а также о данных, отправляемых с мобильного приложения на сервер.

Общие рекомендации для мобильного приложения:

  1. Если вам, как команде разработки, приходит условие «сделать копию интернет-магазина в МП», то необходимо зафиксировать в ТЗ отличия в процессах или функционале.

  2. Рекомендуется заложить в Техническое задание (далее ТЗ):

    1. максимально подробно расписать работу функционала — для исключения разногласий при разработке двумя разными командами Android и iOS.

    2. описание процесса «Что будет происходить в МП, когда пользователь будет удален/заблокирован/деактивирован». Как вариант решения — при ошибке переводить пользователя на экран авторизации.

    3. описание бизнес-процессов по Push уведомлениям для заказов — какие уведомления будут использоваться при изменении статуса заказа и оплаты.

    4. обработку ошибок валидации на каждом экране. Ошибки невалидных данных не должны приводить к падению мобильного приложения или экранов в нем (нужно в модели ответа с бэка задавать опциональные типы, то есть с возможностью установки в null, а потом просто присваивать им значения по умолчанию. В случае, когда эти данные критически важны для работы приложения — выбрасывать исключение, но обрабатывать его, показывая диалог, типа, что-то пошло не так, но не крашить приложение).

  3. Когда разработчик пишет api в postman, необходимо в нем описывать бизнес-процессы — список запросов друг за другом с результатом, чтобы разработчики МП видели как, что и зачем вызывать + приложить примеры ответов с описанием, это позволит другим разработчиком правильно использовать API и не додумывать ничего.

  4. Описывать обязательные/необязательные параметры в запросах/ответах + типы данных.

  5. Учесть проработку экрана стилей для МП, чтобы не рисовать в дизайне все варианты экранов.

  6. Для поддержки версионности предусмотреть передачу из приложения на API параметра version-api — для функционала, который не должен работать без обновления МП, а также параметра user-agent  - для функционала, который должен иметь отличия в зависимости от платформы (Android или iOS).

  7. Изначально реализовать в МП обновление по XYZ-версиям, чтобы не было проблем с обязательным обновлением у будущих пользователей. Наименование версий происходит по шаблону x.y.z, где:

  • x - сделаны обратно несовместимые изменения API;

  • y - добавлена новая функциональность, не нарушающая обратную совместимость;

  • z - обратно совместимые изменения.

  1. Для отладки дать возможность в МП указывать url-обращения (url-сервера). Это даст возможность быстро переключать сборку мобильного приложения между pre и prod сервером для тестирования.

  2. В МП нужны логи запросов/ответов в отладочной версии. Хранение логов в МП.

  3. Создать описание работы headers в запросах — про phpsessid, geolocation и т.д.

  4. Запросы желательно делать фоном для того, чтобы пользователь мог работать в  приложении, а остальная информация догрузится.

  5. Если используется мемкеш, то используем разделенные сессии и не блокирующую сессию.

  6. Для страниц с фильтрами нужны четкие параметры запросов, для того чтобы на разных платформах был один кеш. Необходимо перечислить эти параметры в общем сводном списке для обеих платформ (Android и iOS).

Рекомендации на этапе поддержки МП:

  1. - обязательно оценивать новые доработки задач с учетом старых и новых версий приложений, чтобы не сломалось на старых и работало на новых.

  2. создавать разные ревью площадки на препроде для разделения задач МП. Это позволит ускорить сдачу заказчику задач и уменьшит количество багов при приемке.

  3. продумать функционал для возможности безболезненной авторизации в МП под любым пользователем для отладки и тестирования.

  4. Концептуально приложение рассчитано на «один юзер — одно устройство». Если пользователь сначала залогинился на одном устройстве, а затем зашел в свой аккаунт на втором, то пуш-уведомления будут приходить только на то устройство, на котором пользователь был авторизован в последний раз.  

Уверен, каждый нашёл в этой статье что-нибудь интересное или полезное для себя. Приглашаю вас обсудить и развить тему в комментариях. А с чем сталкивались вы при разработке мобильного приложения на Битрикс REST API? 

Авторы: Буйновский Андрей, Илларионов Антон.

Под редакцией Данильченко Анастасии и Юлии Крайней.

Комментарии (6)


  1. Lainhard
    09.04.2024 12:57
    +2

    Самый большой камень при разработке чего угодно на Bitrix - это Bitrix


    1. m_a_l_o_i_2_0_1_2 Автор
      09.04.2024 12:57
      +1

      Ну у нас была задача сохранить функционал кторый есть на сайте, а он был на Bitrix


  1. koleso_O
    09.04.2024 12:57
    +2

    «Стоит использовать принцип SOLID» - надеюсь, автор просто отпечатался. Solid - это не 1 принцип.


    1. m_a_l_o_i_2_0_1_2 Автор
      09.04.2024 12:57

      Да, опечатка. Было много правок и упустил этот момент. Спасибо


  1. koleso_O
    09.04.2024 12:57
    +2

    «Стоит использовать принцип SOLID, то есть максимально при отдаче данных распределить на как можно больше методов» - я бы отметил, что такой подход не базируется на solid, а скорее является одним из признаков rest-архитектуры. Вы можете иметь несколько репрезентативных состояний одного и того же ресурса, каждое со своей ручкой.

    В целом, большой респект вам за статью, за то, что поделились опытом склейки моб приложений и этого вашего битрикса))


    1. m_a_l_o_i_2_0_1_2 Автор
      09.04.2024 12:57

      Спасибо за отзыв и полезную критику