Приложением «Сбербанк Онлайн» пользуются многие, но мало кто знает, как оно работает. Пришло время приоткрыть завесу тайны — в этой статье мы поговорим о некоторых подходах, которые мы используем при разработке.
Здесь не будет больших данных, блокчейна, agile или прочей ракетотехники.
Но будет описан API, на котором работают наши самые популярные приложения.
Ценность этой статьи не в прорывных идеях, а в подходах и практиках, которые работают в большом приложении с одной из самых требовательных аудиторий.
Мы надеемся, что наш опыт поможет читателям сделать свой продукт лучше, а главное масштабируемым, ведь большую часть ошибок в разработке API мы уже отловили и исправили.
О чем мы будем говорить
Мы расскажем, как работают сценарии оплаты в мобильных и веб-приложениях Сбербанк Онлайн, а именно об API между приложениями и серверной частью.
Почему стоит сосредоточиться на API? Все просто — это фактически единственный мост, соединяющий клиентские приложения и бэкенд. Если проект небольшой, то мы легко можем изменить API и переписать под него приложения.
Но если проект масштабный (как наш), то даже небольшие изменения API требуют задействования большого количества ресурсов как на фронте, так и на бэкенде и становятся очень дорогими.
И второй момент: чем раньше мы исправим API, тем раньше фронт- и бэк-команды смогут начать разработку.
Им просто нужно будет сойтись в одной точке.
Сначала мы немного поговорим о наших возможностях и ограничениях, чтобы было понятно, почему мы выбрали именно это решение, а не другое, а затем представим сам протокол API на верхнем уровне.
Специфика и мотивация
Приложения большие.Когда мы писали эту статью, приложение Сбербанк Онлайн на Android занимало около 800 000 строк кода, на iOS — 500 000 строк кода.
И это только наш код, без подключаемых библиотек.
Обратная совместимость и множество пользователей.
МАУ – 32 миллиона активных пользователей мобильного приложения.
И если мы не сделаем обратную совместимость на уровне API, многим пользователям по всей стране придется скачивать приложения заново.
Это очень плохо.
Кстати, это одна из причин, почему у нас так много кода.
Сбербанк Онлайн разрабатывает множество небольших команд. Вы наверняка слышали об Agile в Сбербанке.
Это правда, мы работаем по Agile в командах по 9 человек.
Банковское приложение: Несмотря на то, что функциональность банковских приложений очень быстро растет, главное, что происходит в ДБО – это последовательный процесс (обработка клиентских заявок).
Мы называем такие процессы рабочим процессом.
Эти заявки могут быть самых разных видов и их обрабатывает огромное количество взаимосвязанных сервисов внутри периметра банка.
Два типа команд. Есть платформенные — они отвечают за разработку ядра приложения.
А есть фиче-команды — они создают функционал приложений для конечных пользователей, используя архитектуру и инструменты, которые предоставляет платформа.
Омниканальность.
Чрезвычайно важная история.
Чтобы не разрабатывать заднюю часть несколько раз - отдельно для мобильных приложений и отдельно, например, для веб-версии и банкоматов, нужно сделать так, чтобы API было максимально схожим для всех каналов (как минимум структура ответа должна быть быть таким же).
Мобильное приложение
Данные изменяются динамически.Самые популярные операции в мобильном приложении — оплата и перевод. Сведения о поставщиках услуг, набор полей, которые должен заполнить пользователь, представляют собой динамическую информацию, которая может часто меняться.
Однако пользователи могут не обновлять приложение, после установки на устройство.
Просто потому, что они могут. Чаще всего для этого есть веские причины, например, чтобы обновить приложение нужно обновить версию ОС, а для этого нужно купить новый телефон.
Поэтому нам нужно решение, которое позволит нам изменять данные, не выпуская приложение.
Мобильный интернет: наши приложения должны работать везде, даже там, где Интернет нестабильный и медленный.
Поэтому мы всегда боремся за размер и количество сообщений между мобильными приложениями и серверной частью.
Лучший клиентский опыт: Мы выбрали для себя основную технологию разработки мобильных приложений – разработку на родных языках.
Это единственный способ получить лучший клиентский опыт. Подводя итог всем этим требованиям, приложения должны быть разработаны на родных языках, иметь в себе повторно используемые компоненты, но вся бизнес-логика должна управляться со стороны сервера.
Как они этого не сделали
После того, как мы определили граничные условия, мы расскажем вам, какие существующие решения мы проанализировали.JSON-программирование Легче императивно описать логику в коде, чем изобретать (и изучать!) новый декларативный язык, который всегда будет более ограниченным, чем родной язык платформы.
Кроме того, необходимо предусмотреть песочницу, обработку ошибок, некий этап пилотирования — псевдокод должен постепенно распространяться на пользовательские устройства и откатываться в случае каких-либо сбоев.
Все это усложняет развитие без ощутимой выгоды.
ЦСС 3000 Мы не используем описания стилей компонентов, поскольку они могут различаться в зависимости от форм-фактора, платформы и даже режима работы (книжная/альбомная ориентация, адаптивность в сети).
Объявления стилей в окончательной реализации всегда будут более качественными, близкими к реальности и более корректными в обработке крайних случаев.
Кроме того, бывает, что компоненты со схожей логикой на разных устройствах работают принципиально по-разному: например, ввод номера телефона — с телефонной книгой на мобильном устройстве и без неё в сети.
Исправление модели данных в интерфейсе приложения Этот метод еще называют «прибиванием».
Дело в том, что интерфейс приложения построен на уникальных идентификаторах объектов, которые передаются с сервера.
В этой схеме любые изменения на стороне сервера приводят к переделкам на стороне клиента.
Невозможно повторно использовать код. Трудно поддерживать.
Единственная причина, по которой вам следует выбрать этот метод для своего проекта, — это 99% уверенность в том, что API не изменится.
Ну, или если проект очень маленький и разработать API дороже, чем быстрая переделка пользовательского интерфейса под изменения API. Стили Мы добавляем атрибут стиля к каждому объекту.
Мы создаем пользовательский интерфейс приложения на основе этой функции.
Количество стилей ограничено, поэтому появляется возможность динамического построения интерфейса.
Но по мере увеличения функциональности пользовательского интерфейса количество стилей должно увеличиваться.
Эта опция дает возможность управлять отображением отдельных элементов, но увеличивает сложность реализации связности между различными полями.
И самое главное, с увеличением вариативности пользовательского интерфейса у вас будет постоянная необходимость расширять протокол API. JSON API ты JSON API Подробно описаны рекомендации по структурированию данных и описанию связей между ними, но нет ничего, что могло бы описать представление.
В нашу задачу также входит визуальное расширение — добавление новых полей ввода, поэтому этот вариант нам не подходит. Веб-компоненты/API компонентов React Концепция веб-компоненты , что также существенно повлияло API компонента React , нас это устраивает гораздо больше: с одной стороны, мы имеем контроль над отображением, с другой — возможность привязывать данные к элементам пользовательского интерфейса.
К сожалению, всё слишком завязано на HTML+CSS+JS. Вы не будете использовать его напрямую, но запомните – он вам пригодится позже.
Как вы решили это сделать?
Контейнеры пользовательского интерфейса Объекты упаковываются в контейнеры, и на этих контейнерах строится логика представления приложения.Основное преимущество заключается в том, что мы можем группировать несколько простых объектов в один контейнер.
Это дает свободу в программировании UX/UI на клиенте, например, мы можем контролировать скрытие/отображение одного поля при заполнении данных в другом.
При этом количество базовых типов объектов ограничено, и на них продается весь бизнес-транспорт. Мы выбрали этот подход. Сначала мы опишем протокол API, а затем то, как фреймворки работают внутри мобильных и веб-приложений.
API
Чтобы было понятнее, давайте рассмотрим API на примере простого процесса, например, перевода между вашими аккаунтами.Мы не рассматриваем, как мы попадаем в точку входа — это не процесс и для этого есть API (о нем мы тоже когда-нибудь поговорим).
Итого, наш процесс начинается с точки входа:
Транспортировка данных
Для начала давайте договоримся об основных принципах — как мы передаем данные.Возьмем за основу самый простой подход — пары ключ-значение.
Пусть ключом будет строка букв латинского алфавита, значением — тоже строки, но произвольные.
Формы для заполнения могут быть сложными, с вложенными элементами и подразделами, а это значит, что вложенность должна быть разрешена.
Ключам можно присваивать имена в формате CamelCase, но они могут быть трудно читаемы (например, в журналах) или даже повреждены в системах, нечувствительных к регистру.
Вам необходимо ввести разделитель.
Самый очевидный разделитель — точка — используется во многих языках для доступа к свойствам объекта.
При неосторожном использовании ключи с таким разделителем создадут словари (или объекты), в которых возможны коллизии.
Например, «foo.bar» = «foobar» и «foo.bar.baz» = «foobarbaz» в javascript может привести к перезаписи свойства «bar» объекта «foo» со строки на объект. В конце концов мы сошлись на двоеточии: с одной стороны, явное визуальное разделение и семантическое отражение вложенности, с другой стороны, вполне безопасно для всех используемых языков.
Что делать с повторяющимися полями? Введем дополнительное правило: между парой разделителей могут быть как латинские буквы, так и цифры.
В результате структуры выглядят так: дети:5:имя:первый .
Прожив некоторое время с этой структурой, мы обнаруживаем ограничение: множественный выбор оказывается нетривиальным в реализации и требует дополнительных ухищрений на бэкенде, чтобы поддерживать высокую нагрузку.
Решение: value — это либо строка, либо список строк.
Так что решение выглядит типовым, но при этом накладные расходы незначительны.
Шаги
Шаг – это состояние процесса.Наш первый шаг — выбрать дебетовый счет и кредитный счет и ввести сумму.
Пользовательский интерфейс не виден на этом изображении, поскольку этот шаг касается логики сервера, а не логики представления.
Есть два подхода к работе с шагами: можно передавать с сервера только разницу (промежуточный итог в клиентском приложении) или каждый шаг целиком (промежуточный итог на сервере).
Анализ требований показал, что в процессе процесса на разных шагах экран может формироваться по-разному (ветвление процесса), поэтому вместо добавления управляющих команд для преобразования уже переданных сущностей проще передать каждый шаг полностью таким, каким его должен видеть пользователь.
.
Дополнительное преимущество: при возврате к редактированию не нужно проигрывать весь скрипт или передавать дополнительный параметр «отдать всё».
При запуске шага клиентское приложение сразу получает всю необходимую информацию для построения экранов.
"output": "screens": "events": "references":
? краны
Кран — это разделение процесса на этапы в клиентском приложении.Обычно экраны используются для облегчения понимания формы.
В нашем случае все просто: один шаг — один экран.
Для экранов мы ввели два правила:
- переход между экранами может быть только линейным, без ответвлений;
- переход между экранами не требует взаимодействия с сервером.
"screens":
Теги: #Разработка мобильных приложений #api #Разработка сайтов #разработка #мобильные приложения #фреймворки #сбербанк #Сбербанк Онлайн #сбертех #sbertech
-
64-Битный Flash Player 11 Для Linux
19 Oct, 24 -
Не Переходи На Темную Сторону
19 Oct, 24 -
Социальные Сети — Самый Жирный Хронофаг
19 Oct, 24