Всем привет! Меня зовут Артём и я разработчик в команде Operations & Support Tools. Наша команда занимается разработкой софта для взаимодействия поддержки с пользователями, с целью решения любых возникших у пользователей проблем. В прошлый раз один из моих коллег рассказывал, как реализовано взаимодействие сервисов у нас в Платформе. Те, кто пропустили эту статью, могут найти её по ссылке. Сегодня я хочу рассказать про приложение, которое раскрыло возможности Contract API с новой стороны. Знакомьтесь, Contract UI. Переход приложений на использование строго формализованных контрактов позволил автоматизировать процессы связанные с созданием документаций для API, и - упростил интеграцию приложений друг с другом. В это же время контракты включают в себя достаточно информации: имена, типы и валидации полей при запросе и ответе от контракта, ссылку на документацию по контракту и тд. Это привело к следующему логическому шагу - разработке сервиса, который позволил бы нам генерировать административный интерфейс на основе коллекций контрактов и встраивать сгенерированный интерфейс в любой из платформенных инструментов. Прошу любить и жаловать: Contract UI (далее CUI)  веб-приложение, созданное в виде магического универсального гаечного ключа, чтобы привести неидеальный UI мир разных приложений к возможно всё ещё не идеальному, но единому UI миру. Если формулировать возможности приложения более чётко, то хотелось получить инструмент, который мог бы следующее: работать с Contract API для получения данных автоматически генерировать виджеты исходя из структуры контракта давать возможность разработчикам кастомизировать базовые элементы UI при помощи JS работать с правами пользователей и настраивать видимость для разных групп пользователей группировать виджеты для подключения одним пакетом обладать простым механизмом интеграции с другими приложениями логировать действия пользователя Немного про архитектуру самого приложения. CUI состоит из двух ключевых частей: админки и публичной части. Админка представляет собой SPA, где собраны все инструменты для создания, хранения, редактирования, удаления виджетов и коллекций, настройки доступа, а также список доступных пермишенов. Публичная часть интегрируется на страницы приложений и отвечает за отрисовку виджетов на страницах. Пройдёмся по каждой из них более детально. Как было сказано выше, CUI Admin представляет из себя страницу для работы с виджетами. Рассмотрим более детально процесс создания виджетов. Создание виджета всегда начинается с выбора контракта, который будет реагировать на запросы из нашего виджета и отдавать данные. Сама структура контрактов хранит достаточно информации, которую можно использовать для создания виджетов. Разбёрем это на примере одного из тестовых контрактов. На Рисунке 1 представлена схема контракта, которая включает в себя четыре поля, три из которых являются обязательными при запросе в контракт.  Каждое из полей в обязательном порядке содержит поле “type”, которое позволяет определить тип UI-элемента, который будет использоваться в виджете, навесить базовые валидации и сохранить финальный тип, к которому при необходимости будет приводиться значение перед отправкой в контракт. Если указаны дополнительные поля по типу максимальной/минимальной длины строкового значения, перечислены возможные варианты для строкового значения, указаны максимальное/минимальное значение для численных, то эти условия также применяются для валидации полей виджета. Автоматически из контракта мы можем получить список полей (Request parameters), которые используются как входные параметры при запросе в контракт, имя виджета и описание ссылкой на документацию по контракту, где можно посмотреть сам контракт и уникальное имя (slug) виджета, которое является уникальным полем для каждого виджета. Любой из перечисленных параметров можно менять по своему усмотрению. Чтобы избавить пользователя от дополнительных кликов и переходов на другие страницы, мы также парсим сам контракт, разбивая его на блоки со схемой запроса, ответа, ошибок. Как можно видеть на Рисунке 2, пользователь также может настраивать области видимости для каждого виджета по отдельности при помощи прав доступа (пермишенов). Для обеспечения единообразного процесса работы с пермишенами пользователей, CUI умеет ходить в API приложения, которое отвечает за доступы пользователей. Создатель виджета может выставить такое количество пермишенов, которое ему будет нужно, в том числе и ни одного (доступен только core admin). Стоит отметить, что CUI умеет не только вытягивать список пермишенов для пользователей, но также создавать и регистрировать собственные пермишены через интерфейс админки.  После выставления базовых настроек пришло время перейти к основной части самого виджета. Виджет состоит из 2-х частей - Request  и Response форм. Для корректной работы с контрактом нам необходимо заполнить и подтвердить Request форму, а данные будут отображаться уже непосредственно на Response форме. Исходя из этого существует несколько типов виджетов:  супер-простые виджеты, которые выводят данные из контракта; простые формы с начислениями игровых элементов пользователям, где пользователь заполняет форму, отправляет её, получает информацию о результате выполнения операции, жмёт кнопку “Повторить” и тд; сложные виджеты, например таблицы логов, где нет визуального разделения между Request и Response формами. Для облегчения жизни пользователей CUI автоматически создаёт виджеты исходя из проанализированных данных контракта. На примере можно видеть, как при выборе контракта, сгенерировался UI виджета. В текущей реализации CUI генератор форм покрывает простые кейсы, т.е. создание формы с полями для ввода текста, чисел или раскрывающихся списков с вариантами выбора. Если требуется добавлять более сложную логику по получению данных, использовать сторонние библиотеки, кастомизировать сгенерированный UI или формировать запрос в контракт с большими вложенностями, то необходимо привлекать разработчиков. После того, как работы по созданию UI виджета и логики его работы завершены, пользователь может выставить дополнительные настройки, позволяющие отключить/скрыть виджет, отобразить/спрятать заголовок виджета, сделать его сворачиваемым. Настройки виджета и что они делают: Enabled - делает виджет активным/неактивным. Если галочка не установлена, виджет не будет отображаться на странице, на которую он добавлен; Show title - отображает/скрывает имя виджета при его отрисовке; Collapsible - позволяет сворачивать разворачивать виджет при нажатии на его имя; Logging и Logging reason - предоставляет логирование действий пользователя из коробки. Т.е. когда пользователь пользуется виджетом и пытается выполнить запрос в контракт после заполнения формы, поверх виджета появляется окно, в котором необходимо указать номер задачи и причину, по которой выполняется это действие. Вкладка “Widgets”, которую можно видеть на Рисунке 9, является аллеей вашей славы хранилищем, где отображаются все созданные виджеты. На этой странице вы можете найти нужный вам виджет, перейти на редактирование какого-либо из виджетов, удалить или создать коллекцию для отображения. Немного про коллекции и группировку виджетов. Коллекция - это абстрактная сущность, которая объединяет виджеты и отвечает за отрисовку их в том порядке, в котором они перечислены в коллекции. Для некоторых приложений, где выполнена интеграция с CUI, коллекции служат инструментом, по которому происходит добавление элементов на страницу и отрисовка самих виджетов. Но сама концепция коллекций и принцип их работы скорее всего будут переработаны в будущих версиях CUI. Это связано с появлением концепции дашбордов, для простого управления наборами виджетов. Впервые закончив виджет со словами “This is my masterpiece” или переделав пятый раз со слезами на глазах и словами “Я сделяль” на устах, пора отобразить наш виджет на публичной части. Сейчас у нас реализовано несколько способов отображения: полная интеграция с CUI и подключение бандла на страницу, а также использование Dashboard UI. Начнем с более старого варианта. Первоиспытателями интеграции с CUI были Backyard и Zendesk. Каждое из этих приложений имеет страницы пользователей или части UI, где должны были располагаться виджеты. Для интеграции публичной части CUI с приложениями было придумано выполнять сборку CUI в JS-пакет (bundle) и подключать его на страницу приложения.  Определенные плюсом этого метода была простейшая интеграция. Все, что нам требовалось это один раз добавить на темплейт страницы скрипт с подключением JS бандла и контейнер, куда пробрасывался список коллекций и в который будет ходить CUI и вставлять свои виджеты. Дальше вся работа перекладывалась на сам CUI. Он брал коллекции и начинал обращаться за данными в контракты, а после получения ответов, рисовал виджеты на странице. Шло время, игры развивались, добавились новые игровые механики, увеличилось количество действий, которые можно выполнять с аккаунтами пользователей. Вместе с играми выросло количество виджетов на странице пользователей, они стали сложнее и больше в размерах. Искать нужную информацию становилось не так удобно, увеличивалось время на поиск нужных виджетов, некоторые из них были доступны только по ссылке, что требовало отдельных кликов, чтобы получить интересующую информацию. Все эти моменты привели к тому, что захотелось создать что-то, что могло бы удовлетворить следующие “хотелки”: настраивать UI персонально под себя;  изменять размеры виджетов;  перестать писать код, чтобы подключать виджеты на страницу. Dashboard UI (далее DUI) - специально разработанный инструмент, который позволяет создавать персональные дашборды. Приложение разрабатывалось, чтобы дать возможность пользователям создать свой фэн-шуй на странице, расположить как им удобно, установить нужные размеры и тд. Всю информацию, которую можно отобразить на странице, DUI получает посредством опроса API приложений, с которыми он интегрирован. Одним из таких приложений и является CUI. Одной из проблем, с которой мы столкнулись при интеграции CUI с приложениями, была плохая масштабируемость UI элементов. Т.е. вёрстка страниц некоторых приложений не позволяла располагать виджеты любых размеров везде, где нам бы этого хотелось. DUI помог решить эту проблему. Он выступает как прослойка между приложениями, которые хранят в себе виджеты и приложениями, где нужны эти виджеты. DUI интегрируется на страницу приложения и, используя HTTP-API, опрашивает другие приложения, чтобы получить список виджетов, которые можно отобразить на странице. Как видно из примеров, DUI позволил нам решить вопросы с размерами и расположениями виджетов на странице. Все виджеты тянутся при помощи API, поэтому больше нет необходимости писать дополнительный код, чтобы отобразить виджет на странице.  Среди дополнительных плюшек, которые получили при создании DUI: возможность создавать приватные дашборды, которые недоступны никому кроме их создателей; возможность создавать несколько дашбордов для определенных нужд пользователей; возможность устанавливать закладки на дашборды, чтобы быстрее находить их в списке других дашбордов После всего вышесказанного хотелось бы отметить, что эксперимент оказался достаточно успешным. CUI представляет из себя MVP реального приложения и требует дальнейшего развития. Сама идея оказалась жизнеспособна и востребована. Сейчас CUI находится в активной эксплуатации несколькими сервисами, собирается фидбек начиная от конечных пользователей, которые работают непосредственно с UI, не имея доступа к коду виджетов, так и от интеграционных команд и команд разработчиков, которые самостоятельно создают собственные виджеты. Среди недостатков текущего MVP можно выделить следующие пункты: автоматическая генерация виджетов работает с простыми контрактами, из-за чего приходится тратить время разработчиков на добавление более сложных структур, элементов и тд; принцип работы приложения по правилу “один контракт - один виджет”, который не позволяет нам использовать несколько разных контрактов, чтобы генерировать фильтры Request и Response формы динамически.  Ближайшие цели, к которым мы уже движемся - это усовершенствование самой CUI Admin. Мы планируем: разнообразить количество элементов, которые можно добавлять из коробки; добавить возможность валидировать поля при помощи UI; сделать саму админку более глобальным узлом, из которого будет производиться автоматическая доставка виджетов на все регионы.