В далёком Контуровском царстве, в чудесном Фокусовском государстве жила-была дружная команда разработчиков. Денно и нощно они создавали интерфейсы для поиска надёжных контрагентов, возводя величественные «палаты» функциональности и прокладывая пути обновлений. Каждый их релиз, аки праздник, мог приходиться даже на пятницу, дабы как можно скорее порадовать народ новыми фичами.
Города в государстве «Фокус» были полностью созданы разработчиками бэкенда. Используя C# на платформе .NET, они формировали и отправляли HTML-разметку, необходимую для построения города.

Спустя некоторое время в Фокусовском государстве появилась возможность на помощь бэкендерам позвать команду маляров-фронтендеров.
Они вооружились модной строительной технологией под названием React и были готовы внести свои изменения в строительство. Новые города они создавали с лёгкостью и изяществом, используя всю мощь React для создания красивых и функциональных интерфейсов. Но при взгляде на старые города только за голову хватались. Нужен был план по переводу городов на React.
С каждым днём государство разрасталось, жители прибывали, и спрос на фичи постоянно увеличивался. Но вот незадача — маляров-фронтендеров не хватало! «Хоромы» возводились, но оставались серыми и невзрачными — некому было их разукрасить.
Дабы ускорить доставку фич и снизить нагрузку на фронтендеров, было решено привлечь необычных существ — примитивов.
Кто такие примитивы

Примитивы те были специальными мастерами для отображения пользовательского интерфейса. Они были сделаны по образу и подобию bem-json.
Эти удивительные создания по воле бэкендера могли преобразить облик многих построек, окрашивая их в цвета и придавая формы, которые им показали фронтендеры. Таким образом примитивы позволяли создавать единое оформление для блоков с разным содержанием.
Рассмотрим поближе, как выглядит такой контракт, который используется как основа для генерации HTML-разметки.
{
"__type": "phonesList",
"version": "atoms",
"phones": [ {
"num": "+7 800 000-00-00",
"rawNum": "88000000000",
"searchCount": 139,
"likesCount": 2,
"dislikesCount": 2,
"hasLike": false,
"hasDislike": false,
"reason": "",
},
{
"num": "+7 (123) 45-67-89",
"rawNum": "8123456789",
"searchCount": 1,
"likesCount": 1,
"dislikesCount": 0,
"hasLike": false,
"hasDislike": false,
"reason": "",
},
{
"num": "+7 (123) 444-55-66",
"rawNum": "81234445566",
"searchCount": 1,
"likesCount": 1,
"dislikesCount": 0,
"hasLike": false,
"hasDislike": false,
"reason": "",
},
]
}
Есть поле с типом постройки (в нашем случае — type phonesList
), какая-то версия (об этом чуть позднее), массив телефонов с различными настройками.
Бэкенд, используя примитивы, как бы наказывает фронтенду: «Вот список номеров, а ты отрисуй мне блок "Телефоны"». Фронтенд, вооружившись примитивом с таким «цветом краски», уже готов к приказу и отображает необходимое.
Фронтенд «встречает» этот контракт подготовленным заранее компонентом, который помещает все полученные данные в хранилище и отрисовывает список телефонов.

Готовый «город» с телефонами выглядит так:

Работа с примитивами
Такой способ взаимодействия между бэкендом и фронтендом не нов. В царстве мобильной разработки популярен метод BDUI (Backend-Driven User Interface), который позволяет оставить всю бизнес-логику на серверной стороне и быстрее доставлять изменения пользователям. В условиях недостатка разработческой силы, быстро меняющихся требований и большого потока новых функций примитивы оказались эффективным решением.
Давайте посмотрим на величественный «город», который построили разработчики с помощью удивительных примитивов. Левую часть города (первую колонку) построила команда «left» примитивов, правую — «right». Эти команды развивались независимо друг от друга и не стремились делиться своими наработками. Они сосредоточились на собственных участках. «left» и «right» как раз и стали теми версиями, которые мы заметили, рассматривая контракт чуть ранее.

С каждым днём новые функции лились рекой, радуя жителей и прославляя команду разработчиков. Шли годы, команда выросла, к строительству предъявлялось всё больше требований, и примитивы постепенно перестали справляться со своими обязанностями. Они могли раскрашивать старые постройки, но с новыми палатами необычной формы возникали трудности.
Обучение одного занимало много ресурсов как у фронтендера, так и у бэкендера. А ежели со временем хоромы перестраивались, то приходилось обучать примитивы заново. В какой-то момент примитивы стали совсем непримитивны, для каждой новой постройки приходилось пересобирать команды примитивов, так как старые совершенно не годились для использования в других частях города. Язык (читай – контракт) двух команд был не совместим, понимание и поддержание примитивов становилось сложным.
Школа примитивов
Однажды храбрый витязь открыл «школу примитивов». Старым работникам он придал подвижности. В инструментах появилась функция renderUniversal
, которая позволила отрисовывать left
и right
примитивы в любом месте страницы.

Младые левые и правые примитивы витязь разделил на маленькие примитивчики и обозначил их версией atoms
.

Атомы сами по себе умеют очень мало, но вместе составляют мощную строительную команду. Разные комбинации таких команд могут «разукрасить» уникальные новые палаты.

Вы токмо посмотрите на это диво дивное да чудо чудное — примитив, что способен кнопку изобразить (button
).

Есть и другой примитив, что может текст начертать (text
).

Есть примитив, что все предыдущие разукрасить способен, и тот, что умеет в ссылку текст облачать, а другой подсказку текстовую на любой из примитивов поместить может.
Рассмотрим небольшой пример. В нём примитив vertical
принимает массив элементов, которые он выстроит вертикально, подобно привычному для нас:
display: flex;
flex-direction: column;
stylized
принимает text
и добавляет ему семантический тег <h3>
. Чуть ниже другой stylized
задаёт тексту серый цвет и размер шрифта small
(равный 12px).
{
"__type": "vertical",
"version": "atoms",
"content": [
{
"__type": "stylized",
"version": "atoms",
"content": [
{
"__type": "text",
"version": "atoms",
"text": "Уставный капитал: 123 руб."
}
],
"semanticComponent": "h3"
},
{
"__type": "stylized",
"version": "atoms",
"color": "textGray",
"content": [
{
"__type": "text",
"version": "atoms",
"text": "01.01.2000"
}
],
"fontSize": "small"
}
],
"gap": 0
}
Выглядит довольно просто. Примитивы стали более гибкими и функциональными: теперь они могут не только преобразить облик построек, но и отправить метрику в вестник, и вызвать богатырей из центра поддержки. Однако из-за многообразия «мастеров» и их способностей стало сложнее разобраться, какой именно примитив нужен для конкретной задачи. Поэтому бэкендерам приходится обращаться за помощью к фронтендерам, дабы составить правильный контракт и собрать нужную бригаду работников.
Песочница
Для облегчения создания такого контракта и локальной проверки отображения интерфейса была создана специальная песочница.
Давайте посмотрим, как с ней работать. Сначала мы видим примитив text, затем icon
, далее в button
вставим иконку и текст. Обернём кнопку в hint
для добавления подсказки при наведении.

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

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

В результате работы над задачей пришлось добавить несколько примитивов и внести изменения в уже существующие.
Давайте проанализируем отчёт по строительству (читай – MR). Здесь видно сколько правок связано именно с «обучением маляров» (изменением примитивов).

В button
пришлось добавить тип, позволяющий рисовать градиентные обои, в stylized
добавили свойства, которые помогают стилизовать тултип, так же в нескольких местах расширили функцию отправки метрики (так как необходимо было отслеживать показ, открытие и закрытие тултипа) и многие другие мелочи, которые не могли быть реализованы без доработок. Эти правки потребовали ресурсы разработчиков со всех сторон. Автоматической кодогенерации для примитивов нет, поэтому все добавления и изменения полностью пишутся руками.
Шло время, скорость доставки специфических фич стала снижаться, преимущества примитивов над обычным контрактом постепенно теряются.
Бэкендеры уже не хотят повелевать примитивами, им кажется, что реальность похожа на страшный сон, в котором кисточки теперь не только у фронтов, но и у них. Им приходится «красить здания» и «клеить обои» вместо простой доставки стройматериалов. Такое положение дел совершенно не устраивает бэкенд-разработчиков и вносит некоторую напряжённость во взаимодействие команд. Вдобавок, внесение правок в контракт примитивов на бэкенде имеет прямое влияние на изменение интерфейса, что ломает тесты и как следствие усложняет релизный цикл.
Порог вхождения в понимание работы с примитивами с обеих сторон разработки достаточно высокий. Понять, как работать с примитивами, непросто. И для фронтенд-разработчиков, и для бэкендеров это как изучение нового языка. И если познакомиться с командой «atoms» можно с помощью документации и песочницы, то «left» и «right» приходится познавать «на ощупь». Пополнение команды разработчиков Фокусовского государства несёт под собой затраты на то, чтобы новый сотрудник вник в особый способ взаимодействия клиентской и серверной частей.
Заключение
Примитивы из команды «atoms» периодически пополняются новыми кадрами, которые добавляют разнообразия в постройки города. Расширяются возможности уже «бывалых» «left» работяг, а «right» постепенно отправляются на пенсию.
Дальнейшая судьба примитивов нынче покрыта завесами тайн и неопределённостей. В ближайшие полгода мы будем придерживаться текущей парадигмы. Далее команде разработчиков предстоит ряд встреч для решения судьбы примитивов. Необходимо рассмотреть все плюсы и минусы работы с примитивами, проанализировать возможные риски и перспективы. Затем будет разработан план действий с учётом выбранного варианта.
Возможно, примитивы сменятся на жёсткие контракты, а может они выйдут на новый уровень абстракции. Буду благодарна, если кто-то из вас, кто уже работал с подобным инструментом, сможет поделиться своим опытом и впечатлениями.
Доселе эти маленькие «маляры» продолжают делать своё дело — служить на благо Фокусовского государства, а что с ними будет в будущем — покажет время.
Буду рада, если вы получили удовольствие от этого рассказа, вынесли какие-то выводы или идеи, прокрутили мысль о том, что точно сделали бы лучше. Это значит, что моя история была поведана не зря.
