Перейти к основному содержимому

Server Driven UI (SDUI)

Server Driven UI (SDUI) — архитектурный подход, при котором сервер определяет не только данные, но и структуру пользовательского интерфейса (какие компоненты, в каком порядке и с какими параметрами отрисовать на клиенте).

В обычном приложении клиент «знает», как показать экран. В SDUI клиент превращается в «движок рендеринга» — он просто отрисовывает то, что пришло с сервера в виде декларативного описания (обычно JSON).

Подход также называют BDUI (Backend-Driven UI).


В традиционной (client-driven) модели сервер отдаёт только данные, а клиент решает, как их показать:

  • Сервер → отправляет данные ({"price": 1990, "currency": "RUB"})
  • Клиент → знает, как отобразить эти данные на конкретной платформе

В SDUI сервер отдаёт описание интерфейса:

  • Сервер → отправляет компоненты и их свойства ({"type": "price_label", "props": {"text": "1 990 ₽"}})
  • Клиент → по описанию собирает экран из готовых нативных компонентов

Ключевое отличие: логика «что и где показать» переезжает с клиента на сервер.

Client-Driven UI vs Server-Driven UI

КритерийClient-Driven UI (традиционный)Server-Driven UI (SDUI)
Что отдаёт APIДоменные данные (числа, флаги, статусы)Готовый к показу контент (строки, компоненты, действия)
Где живёт логика отображенияНа клиенте, отдельно под каждую платформуНа сервере, единая для всех платформ
Изменение интерфейсаРелиз в сторах + обновление у пользователяПравка на сервере — мгновенно для всех
A/B-тесты и персонализацияНужны отдельные версии клиентаРазный ответ сервера разным сегментам
Офлайн-работаРаботает полноценноЗависит от сети, нужны кэш и фолбэки
Зависимости платформUI пишется отдельно для iOS / Android / WebОдин JSON рендерится на всех платформах
Сложность стартаНизкаяВысокая (нужна инфраструктура и UI-кит)

Как работает

Система состоит из трёх частей:

  1. UI-кит (компонентная база) — набор реализованных на каждой платформе нативных компонентов (кнопка, карточка, баннер, список). Это «общий язык» между сервером и клиентом.
  2. Движок рендеринга — клиентский механизм, который по описанию из JSON собирает экран: находит нужный компонент в UI-ките и передаёт ему свойства.
  3. Контракт (директивы) — описание экрана, которое сервер отдаёт клиенту.

Типовой поток:

  1. На сервере формируется описание экрана (какие компоненты, порядок, свойства, действия).
  2. Клиент запрашивает конфигурацию и получает JSON.
  3. Движок рендеринга разбирает JSON, по type находит компоненты в реестре и отрисовывает их.
  4. Пользователь взаимодействует (например, нажимает кнопку) — клиент выполняет действие (action), пришедшее вместе с компонентом.
  5. Нужно поменять экран — правка конфигурации на сервере, при следующем открытии приложения пользователи видят новый UI без обновления из стора.

Как устроен JSON-контракт

Каждый компонент описывается минимум двумя свойствами:

  • id — идентификатор экземпляра (нужен для точечного обновления и аналитики)
  • type — тип компонента (какой элемент UI-кита использовать)

Плюс props (свойства: текст, цвет, картинка) и опционально action (что сделать при нажатии).

Пример описания экрана:

{
"type": "screen",
"id": "home",
"components": [
{
"type": "header",
"id": "greeting",
"props": {
"title": "Привет, Иван!",
"subtitle": "Добро пожаловать"
}
},
{
"type": "promo_card",
"id": "promo",
"props": {
"title": "Акция дня",
"subtitle": "Скидка 50%",
"image": "https://example.com/promo.png"
},
"action": {
"type": "navigate",
"target": "promo_screen"
}
}
]
}

Чтобы не гонять тяжёлое описание всей формы, используется заготовка экрана (шаблон) — JSON без конкретных данных. А сами данные приходят «облегчённо», с привязкой к id нужного компонента.

Принципы SDUI

  • Начинать с экрана, а не с данных. API проектируется под то, что нужно показать, а не под структуру БД (demand-driven подход).
  • Минимум логики на клиенте. Любой if/else про «что показать» — кандидат на переезд на сервер. Иначе логика дублируется на каждой платформе.
  • Отдавать продуктную информацию, а не доменные данные. Вместо price: 1990 + currency сервер сразу отдаёт готовую строку "1 990 ₽". Форматирование, локализация, скругления — на сервере.
  • Единая дизайн-система. Все клиенты используют общий UI-кит, тогда серверная инструкция «отрисуй primary-кнопку» даст одинаковый результат везде.
  • Внедрять инкрементально. Не переписывать всё приложение сразу, а начать с одного экрана или компонента (например, баннера на главной).

Плюсы и минусы

Плюсы:

  • Мгновенные обновления UI — без релизов в сторах и ожидания обновления у пользователей
  • Кроссплатформенность из коробки — один JSON рендерится на iOS, Android, Web
  • Простой A/B-тестинг и персонализация — разный UI разным сегментам одним изменением на сервере
  • Единообразие платформ — все клиенты синхронны, расхождений почти нет
  • Снижение нагрузки на мобильную разработку — фронт не верстает каждый экран с нуля

Минусы:

  • Зависимость от сети — без интернета UI не загрузится; нужны кэширование и фолбэки, иначе пустые экраны
  • Высокая сложность старта — нужен UI-кит, движок рендеринга и серверная часть под это
  • Двойная поддержка компонентов — компоненты живут и на клиенте (реализация), и на сервере (описание)
  • Сложнее отладка — труднее понять, почему экран выглядит именно так (собрался динамически)
  • Риск «зашить» бизнес-логику в UI — границы между слоями легко размыть

Типичные ошибки

  • Отдавать доменные данные вместо продуктовых. Клиент форматирует и решает «что показать»

    → Сервер должен возвращать готовые к показу строки и компоненты.

  • Забыть про обратную совместимость. Новый компонент пришёл, а старая версия приложения о нём не знает → падение или пустой экран.

    → Версионировать контракт и закладывать поведение «неизвестный тип = игнорируем». Подробнее про обратную совместимость.

  • Сделать всё серверным сразу. Перевести на SDUI всё приложение разом — раздувается инфраструктура и ломаются стабильные экраны.

    → Внедрять поэтапно, начиная с часто меняющихся экранов (главная, промо, баннеры).

  • Дублировать логику между платформами. Часть «что показать» осталась на клиентах — теряется главный смысл подхода.

    → Если логику пришлось менять на одном клиенте — её место на сервере.

  • Игнорировать офлайн-сценарии. Пользователь без сети получает пустой экран.

    → Кэшировать последнюю конфигурацию и показывать её как фолбэк.

Где используется

Где много платформ, а интерфейс меняется часто и под разные сегменты пользователей:

  • Travel- и маркетплейс-платформы — быстрые итерации UI в разделах с динамическим контентом

  • Соцсети и стриминговые сервисы — мгновенный rollout изменений и экспериментов

  • E-commerce и маркетплейсы — разные раскладки витрин для разных продавцов (например, блок «Бестселлеры» только для крупных магазинов)

  • Когда нужно обновлять интерфейс с сервера, не зависеть от сторов

Инструменты и фреймворки

  • DivKit — open-source SDUI-фреймворк от Яндекса: JSON-описание → рендер на iOS, Android, Web. (GitHub)
  • Nativeblocks — платформа server-driven UI с блоками
  • GraphQL + Apollo — типизированная схема удобна для SDUI: union-типы позволяют серверу вернуть разные компоненты, а клиенту — обработать любой. См. GraphQL
  • BFF (Backend for Frontend) — технология (прослойка), которая преобразует доменный ответ бэкенда в SDUI-директивы; один сервер может обслуживать и SDUI-, и обычные клиенты

Материалы

  1. Чем полезен Server Driven UI
  2. Яндекс выпускает DivKit — фреймворк для server-driven UI с открытым кодом
  3. Server Driven UI в Альфа-Банке
  4. Server-Driven UI архитектура: server-driven vs content-driven
  5. Как работает Server-Driven UI и зачем он фронтендеру
  6. Server-Driven UI — документация MoonShine
  7. Backend-for-Frontend: когда простого API не хватает
  8. Не всё деплоем правится: как мы вынесли интерфейс из кода с помощью Server-Driven UI
  9. Эволюция Server-Driven UI: динамические поля, хэндлеры и многошаг
  10. BDUI: эволюция динамических интерфейсов
  11. Продаём тимлиду идею Server/Backend-Driven UI
  12. SDUI, или Как backend-разработчику почувствовать себя frontend’ером

Видео

  1. BDUI — что это и зачем на примере DivKit
  2. DivKit. Server Driven UI. Как это работает #3
  3. Backend-Driven UI и DivKit — ШМР Android 2024
  4. Server-driven UI на примере фреймворка DivKit
  5. SDUI: как сделать дизайнера разработчиком, не заставляя писать код. Сергей Мухин, ВкусВилл
  6. Делаем простейшую имплементацию SDUI // Демо-занятие курса «Android Developer. Professional»

Конференции