Продаём тимлиду идею Server/Backend-Driven UI

<p>Авторское видение обложки к статье</p>

Авторское видение обложки к статье

Привет, меня зовут Андрей Гончаров, я Frontend Developer в Mish Product Lab. Сегодня подробно разберёмся, что такое Server/Backend-Driven UI, как с ним работать и зачем он вообще нужен.

Что такое Backend-Driven UI?

Backend-Driven UI (или Server-Driven UI) — это концепция в разработке приложений с интерфейсом, при котором бэкенд управляет как данными приложения, так и его внешним видом. Например, для фронтенд-приложения BDUI будет управлять вёрсткой.

Есть разные уровни «проникновения» этой концепции в фронтенд-приложение, но лучше это представить как спектр.

<p>Да, кстати, об этом статью сейчас не написал только ленивый</p>

Да, кстати, об этом статью сейчас не написал только ленивый

Кейсы

Проще всего эту концепцию представить через кейсы. Вот парочка:

Кейс #1: страница оформления заказа (aka checkout)

Обычно заказ оформляется в несколько шагов: выясняем способ получения, способ оплаты, контактные данные, делаем оплату. Бизнесы бывают разные, и логика формирования шагов такая же. Шаги же, по сути, представляют собой формы с полями ввода. На фронтенде нам нужно организовать отрисовку полей форм, переходы между шагами и отправку данных. Остальная логика возлагается на бэкенд.

Яркий пример — CS-Cart.

<p>Примерная логика формирования шагов чекаута в интернет-магазинах</p>

Примерная логика формирования шагов чекаута в интернет-магазинах

Кейс #2: пост в блоге

Обычно посты в блогах пишут в админке блога в WYSIWYG-редакторе. Некоторые современные редакторы предоставляют многоколоночное оформление контента, кастомные компоненты, накидывают SEO, тегов и прочих ништяков. Бэкенд хранит записи, организует управление и доступ к ним. Фронтенд из структуры документа формирует верстку.

Яркий пример – Strapi.

Кейс #3: быстрая доставка улучшений интерфейса без обновления приложения

Представим, что вы — банк, который оказался под санкциями: ваше приложение скрыли из всех магазинов, вы не можете доставить пользователям новые обновления. Но у вас есть выход, ведь весь интерфейс приложения приходит в виде JSON с сервера!

Яркий пример — DivKit. https://habr.com/ru/company/yandex/blog/683886/

Зачем реализовывать эти кейсы при помощи данной концепции?

Потому что мы хотим:

  • Значительно поменять Layout фронтенд-приложения (кейс #3).
  • Изменить структуру какого-то экрана в приложении (кейс #3).
  • Внедрить A/B-тестирование (кейс #3, кейс #1). Представьте, какая это боль, когда такие тесты на гипотезы надо писать руками, деплоить в отдельные версии/бандлы и так далее.
  • Срочно добавить дополнительное промо от отдела маркетинга.
  • Добавить страничку с каким-то контентом.

Что может пойти не так, если отказаться от BDUI

Для каждого отдельного члена команды свой сценарий развития событий:

  • Для проджекта нужно будет учитывать сложность изменения структуры страницы. Конечно, есть тимлид, который подскажет. Но что, если он тимлид-джун без опыта?
  • Для тестировщиков изменение глобальных частей с захардкоженной структурой практически всегда триггерит полный регресс. Нет уверенности в том, что полный ручной регресс не вызывает боль. Но точно есть сценарий с отсрочкой релиза на пару дней.
  • Для программистов можно выделить следующие больные моменты кратко:
  • изменения в структуре нужно зафиксировать в коде, то есть сесть и сверстать;

  • внешние источники данных нужно интегрировать для новых блоков;
  • необходимо контролировать удаление источника данных при удалении блока;
  • нужно встроить новый блок в существую верстку или же адаптировать верстку при удалении блока.

Что насчет сроков? Негативный кейс

Давайте рассмотрим кейс, в котором у нас заказывают небольшой сервис бронирования койко-мест. У нас есть дизайн, по которому мы верстаем, есть договор, определяющий функционал и сроки. Есть реальная действительность, где перед дедлайном просят поменять местами промоблок и компонент «селектор койки».

Казалось бы, в верстке меняешь два компонента местами — готово. Но есть вероятные технические блокеры:

  • фронтендер мог верстать страницу изначально с этими блоками, делая хардкод в размерах, отсупах и так далее;
  • источники данных могут требовать какой-то определенный порядок запроса данных;
  • код может быть «грязным», а понимающий его синьор — в отпуске.

Ещё есть минус от хардкоженной структуры UI, не очень очевидный: у страницы нет контракта с точки зрения его структуры и данных. Мы можем понять, какие данные придут, но только после изучения кода. Как и узнать раскладку блоков в верстке.

А как быть с добавлением новой страницы с текстовым контентом?

  • Нужно залезть в код и скопировать типовую страничку с её layout — по сути копипаст бойлерплейта.
  • Может потребоваться зарегистрировать страницу в роутере приложения, закрыть за авторизацией.
  • Необходимо подрубить источник данных.

С такой ментальной моделью приложения сложно будет сделать следующее:

  • Проводить A/B-тестирование.
  • Добавлять новый контент на сайт без привлечения отдела разработки.

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

По сути, вся техника Backend-Driven UI сводится к получению схемы экрана от бэкенда, к дальнейшей обработке и рендерингу. Часто даже с получением карты сайта.

Как получить удобный BDUI

Что нам нужно учитывать, чтобы получить удобный Backend-Driven UI?

  • Контракт от бэкенда. Нужно понимать, в каком формате будет приходить лейаут экрана.
  • Начальное состояние компонента. Если оно нужно, то как лучше его инкапсулировать?
  • Степень, до которой BDUI описывает layout. Сюда входит расположение и вложенность блоков, их горизонтальное или вертикальное расположение на странице, размеры блоков.
  • Параметры страницы. Среди них номер страницы, фильтры и так далее.

Как это сделать?

Лучше всего, как я выяснил, выделять логику формирования интерфейса в отдельный микросервис, Backend For Frontend. Не стоит запихивать в бэкенд проекта логику для полиморфного отображения. Да, есть случаи как в кейсе #1, но мы сейчас про макет.

Кто и как применяет в индустрии BDUI?

Пример #1. Бигтех, Ozon

Приложение Ozon для смартфонов сделано по этой концепции. Применяют они её по ряду причин:

  • для A/B-тестирования;
  • чтобы вытащить бизнес-логику из Web/Android/iOS приложений;
  • для более быстрой доставки изменений пользователям.

Вот классная статья, где они рассказывают о том, как готовили логику формирования интерфейса: https://habr.com/ru/company/ozontech/blog/661941/

Скриншот приложения с пояснениями по виджетам на страницы, скрин из статьи Ozon
Скриншот приложения с пояснениями по виджетам на страницы, скрин из статьи Ozon

Пример #2. Бигтех, Альфа

Хорошая статья на Хабре, где инженеры Альфа-банка делятся своим опытом: https://habr.com/ru/company/alfa/blog/668754/

Отмечу, что они рассказывают не столько про компоновку, сколько про всё остальное: обработка событий, бизнес-логика в сложных формах.

<p>Сриншот из статьи с примером обработки событий</p>

Сриншот из статьи с примером обработки событий

Пример #3. Бигтех, Airbnb

Ныне почивший в России букинг-сервис Airbnb. Да, их мобильное приложение также построено на концепции BDUI. Применяют они её для A/B-тестирования. Вот приправленная кодом статейка с их рецептом: https://medium.com/airbnb-engineering/a-deep-dive-into-airbnbs-server-driven-ui-system-842244c5f5

Вот так Airbnb трансформирует данные в UI. Скрин из их статьи
Вот так Airbnb трансформирует данные в UI. Скрин из их статьи

Пример #4. No-code, Unflow

Да, такая модная тема как no-code зачастую заходит в клиентские приложения через BDUI. Так, Unflow оставляет свободу для кастомизации и предоставляет SDK для мобильных платформ: https://github.com/unflowhq

<p>Вот как выглядит редактор экранов в Unflow</p>

Вот как выглядит редактор экранов в Unflow

Пример #5. No-code, Strapi

Интересный пример реализации — Strapi, Headless CMS. Она даёт интерфейс для редактирования контента и не формирует отображения, не генерирует сайт. Так можно создать сущность «макет страницы» и в него накидывать блоки страницы. Но это совсем неудобно. И ещё нет возможности удобно впилить другие источники данных.

<p>Админка Strapi</p>

Админка Strapi

Пример #6. Реализация концепции в CMS CS-Cart

Есть другой пример реализации, так называемый Block Manager. По сути, это упрощенный визуальный редактор макета страницы. Позволяет собрать/пересобрать страничку, вообще не прибегая к написанию кода. Настройки блоков/виджетов — отдельная мультивселенная.

<p>Редактор макетов страницы</p>

Редактор макетов страницы

Выводы

Backend/Server-Driven UI всё же узкоспециален. Реализация полноценного интерфейса в такой парадигме — задание со звёздочкой в квадрате, готовое съесть много денег бизнеса. Поэтому отлично заходит этот подход либо для очень крупного, либо для малого бизнеса. Да и выглядит это как некий Trade-off в обоих случаях.

  • Очень крупному бизнесу нужно проверять гипотезы, быстро поставлять фичи/заплатки и не сгореть в аду дублирующейся бизнес-логики в разных клиентских приложениях.
  • У малого бизнеса нет ресурсов для своих решений, эти ребята берут no-code платформы, которые в основном BDUI, накидывают экраны, настраивают open-source клиент на свой инстанс в платформе, и всё работает.

Но концепция хороша, и применять её точечно в определенных местах (типа сложных форм) — однозначно правильное решение. Чем больше бизнес-логики на сервере, и меньше на клиенте — тем крепче спится.

Поделиться рецептом?

Хорошо, что мы можем сделать BFF для Backend/Server-Driven UI самостоятельно. Есть рецепт от меня, но он слишком большой для этой статьи. :)

Дайте шума в комментариях, выпустим сиквел :)

1010
Начать дискуссию