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-кит) |
Как работает
Система состоит из трёх частей:
- UI-кит (компонентная база) — набор реализованных на каждой платформе нативных компонентов (кнопка, карточка, баннер, список). Это «общий язык» между сервером и клиентом.
- Движок рендеринга — клиентский механизм, который по описанию из JSON собирает экран: находит нужный компонент в UI-ките и передаёт ему свойства.
- Контракт (директивы) — описание экрана, которое сервер отдаёт клиенту.
Типовой поток:
- На сервере формируется описание экрана (какие компоненты, порядок, свойства, действия).
- Клиент запрашивает конфигурацию и получает JSON.
- Движок рендеринга разбирает JSON, по
typeнаходит компоненты в реестре и отрисовывает их. - Пользователь взаимодействует (например, нажимает кнопку) — клиент выполняет действие (
action), пришедшее вместе с компонентом. - Нужно поменять экран — правка конфигурации на сервере, при следующем открытии приложения пользователи видят новый 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-, и обычные клиенты
Материалы
- Чем полезен Server Driven UI
- Яндекс выпускает DivKit — фреймворк для server-driven UI с открытым кодом
- Server Driven UI в Альфа-Банке
- Server-Driven UI архитектура: server-driven vs content-driven
- Как работает Server-Driven UI и зачем он фронтендеру
- Server-Driven UI — документация MoonShine
- Backend-for-Frontend: когда простого API не хватает
- Не всё деплоем правится: как мы вынесли интерфейс из кода с помощью Server-Driven UI
- Эволюция Server-Driven UI: динамические поля, хэндлеры и многошаг
- BDUI: эволюция динамических интерфейсов
- Продаём тимлиду идею Server/Backend-Driven UI
- SDUI, или Как backend-разработчику почувствовать себя frontend’ером
Видео
- BDUI — что это и зачем на примере DivKit
- DivKit. Server Driven UI. Как это работает #3
- Backend-Driven UI и DivKit — ШМР Android 2024
- Server-driven UI на примере фреймворка DivKit
- SDUI: как сделать дизайнера разработчиком, не заставляя писать код. Сергей Мухин, ВкусВилл
- Делаем простейшую имплементацию SDUI // Демо-занятие курса «Android Developer. Professional»
Конференции
- Yandex BDUI Conf 2024 — конференция Яндекса и Яндекс Маркета по BDUI/SDUI
- Mobius: Абакар Магомедов и Владислав Чешенко — Figma Mockup to Server-driven UI
- Mobius:Абакар Магомедов, Александр Гирев — Паттерны SDUI
- Артём Федотов, X5 Tech — От натива до SDUI через гибрид - Дмитрий Жердев — BDUI – удовольствие или боль?