Привет! Меня зовут Алексей, я аналитик данных в команде BI финансового маркетплейса Банки.ру. Сегодня хочу поделиться опытом работы с Appsmith. Это low-код инструмент для автоматизации бизнес-процессов.
В статье расскажу:
зачем вообще нам понадобился подобный инструмент
почему мы выбрали appsmith и чем он нам понравился
на кейсах разработки подробнее раскрою его возможности и функциональность
С чего все началось
Наша команда собирает данные для организации сквозной аналитики в Банки.ру. Мы настраиваем приложения, проектируем отчетности для каналов, маркетплейсов, разрабатываем отчеты финансов и маркетинга, дашборды и прочее.
Отчетов мы готовим много, большинство данных есть в нашей базе, поэтому мы можем работать с ними в автоматическом режиме. Но мир не идеален, и иногда нужных данных в источнике нет. В таких случаях нам приходится собирать их от пользователей вручную.
Данные мы обрабатываем в Postgres, поэтому нам нужно было решить, каким образом их туда доставлять.
Начали мы с использованиям связки Excel+Pentaho, благодаря которой данные загружались в Postgres, на их основе можно было делать отчеты в Tableau.
Но у такого подхода были свои недостатки.
Во-первых, это сложности в работе в многопользовательском режиме: кто-то забыл выйти из файла, он стал недоступен для редактирования другим пользователем, или кто-то что-то нажал и все сломалось, причем сразу у всех. При этом возможности отслеживать историю изменений не было.
Уведомления о том, загрузились ли данные вообще, тоже появлялись. Пользователям приходилось ждать, пока они отобразятся в финальной отчетности, и если их там не было, весь процесс начинался сначала.
При этом отчетов и пользователей меньше не становилось, поэтому мы начали искать другой способ. Собрали требования к инструменту, который поможет нам решить задачу.
Среди них:
не Excel ????;
простое развертывание и эксплуатация;
высокая скорость разработки;
процесс должен выполняться на стороне аналитика без участия разработчиков;
low-код и no-код решения подходят.
Проанализировали, что предлагает рынок, и выбрали три решения: Retool, Budibase и Appsmith. Изучили и протестировали их и довольно быстро решили остановиться на Appsmith.
Почему Appsmith
Это удобный инструмент для автоматизации и разработки собственных web-приложений, таких как CRUD-интерфейсы, дашборды, админки и прочее. Его можно развернуть в Docker или Kubernetes, а можно использовать в облаке. Под капотом — JavaScript, который можно использовать в любых элементах приложения.
Мы начали пользоваться им с лета 2022 года, и сейчас у нас более 30 приложений и свыше 80 активных пользователей.
Как мы использовали Appsmith при создании CRUD-интерфейса и что пошло не так
На первом этапе у нас была эйфория от нашей находки. Мы отказались от связки Excel+Pentaho, насоздавали кучу админок, с помощью которых можно было заливать данные в хранилище. Схема была простой: пользователь взаимодействовал с Appsmith, загружая данные построчно, а Appsmith был связан с целевой таблицей в Postgres. Процесс шел быстро, все были довольны.
Но, как я уже говорил, мир не идеален: эйфория сменилась разочарованием.
Появились требования, когда нужно было заливать CSV-файл в Appsmith. Вроде ничего сложного — добавили такую возможность. В приложении по ссылкам были доступны для скачивания типовые шаблоны для загрузки (которые нужно было актуализировать в случае доработок).
Данных тем временем стало больше.
Появилась необходимость контролировать и сверять значения, которые попадают в целевую таблицу со справочником из Postgres, чтобы еще в процессе загрузки понимать, что данные корректные. Если нет — быстро давать пользователю обратную связь.
Следующая сложность: если файл грузится неоднократно, нужно проверять уникальность данных. Опять же, делать это нужно на этапе загрузки, а не после появления данных в БД.
Так как количество пользователей тоже росло, мы пришли к необходимости контролировать доступ и фиксировать изменения. Значит, нужны было не только персональные доступы, но еще и логирование операций.
Затем появился проект, который предполагал загрузку файлов с большим количеством строк — до 50 тысяч. Так как загрузка была реализована через SQL INSERT VALUES (array из Appsmith), Appsmith зависал при выполнении такого запроса. Опытным путем установили что существует ограничение — не более ~1500 строк. Кроме того, нельзя было отобразить результат SQL SELECT запроса: если он был больше 5mb, он просто не грузился.
К этому прибавилась сложность работы с разными интерфейсами: админок же было много. В результате вместо одного инструмента загрузки у коллег появилось несколько, выглядящих по-разному. К каждому нужно было привыкать и учиться с ним работать – это очень неудобно.
С поддержкой данных приложений дела тоже обстояли плохо: приходилось дорабатывать каждое приложение в отдельности. Мы ориентировались на четкую структуру и во всех скриптах hard-кодили ее. Добавление нового поля в таблицу и необходимость загружать в него данные через Appsmith приводили к тому, что приходилось заново лезть в приложение и все править. Сложно, трудоемко, дорого.
Одним словом, накопилось.
Делаем работу над ошибками
Мы поняли, что закрывать эти вопросы в рамках разных админок/приложений — идея безумная. Пришли к тому, что все нужно унифицировать и создать универсальное приложение, которое при этом будет допускать большую вариативность при загрузке данных, гибкость и скорость внедрения изменений.
Пришли к следующей схеме:
Сделали настроечную таблицу, которая определяла структуру данных под приложением. Одна для всех.
Научились загружать большое количество строк путем пакетной загрузки в JSON формате.
Настроили автоматические JSON-формы для ручной загрузки, которые формировались «на лету».
Настроили автоматическое формирование шаблона загрузочного файла на стороне Appsmith.
Чтобы валидировать большое количество записей, создали единую буферную таблицу. Так валидация происходила на стороне Postgres и не грузила Appsmith. Проверка типов данных тоже ушла на сторону Postgres.
Чтобы справиться с отображением результатов больше 5mb, сделали пагинацию на стороне БД. Автоматически прописали лимиты, офсеты из параметров табличных виджетов. Это помогло нам не грузить весь объем данных, а только то, что может отображаться в виджете. Если объем большой, то данные подгружаются после запроса — клика на кнопку переключения страницы виджета.
Организовали логирование по SCD второго типа: добавляем новые версии строк и предыдущие делаем неактивными. Появляется история: кто менял и что изменилось.
Магия настроечной таблицы
Это виджет, в котором мы добавили настройки: какой справочник контролирует данные, в какую целевую таблицу они выгружаются, учли возможность регулирования пакета загрузки и версионирования.
В самой таблице мы автоматически можем подгрузить структуру данных из схемы Postgres и определить поведение колонок:
какие использовать для формирования шаблона и загрузки данных, а какие можно пропустить
по каким ключевым полям будем определять, изменились ли данные
задать поля, которые нужны для автоматического формирования json формы ввода данных.
Когда нестандартных требований нет, развертывание приложения занимает около 10 минут.
А теперь магия!
Данные из такой таблицы мы используем в админке через JS переменные в SQL запросах (похоже на JINJA template). Есть скрипт, который собирает данные из настроечной таблички, компилирует их и на выходе превращает в SQL-код. Все это происходит автоматически. То есть мы один раз задали структуру трансформации данных – и добавление нового поля больше не становится проблемой.
Загрузка больших файлов в Appsmith с помощью JSON
Чтобы справиться с ограничением по объему загрузки, мы делим файлы на пакеты при помощи JS функции и на каждой итерации загружаем через SQL запрос во временную таблицу в БД, используя JSON формат. Если загрузка вдруг упала на середине, процесс останавливается, а пользователь получает уведомление о том, что файл некорректный.
После того, как файл полностью загрузился, мы парсим полученные JSON пакеты, используя json_to_record, получаем данные в табличном виде и формируем превью для последующей финальной загрузки в целевую таблицу.
На этапе формирования превью происходит сверка данных со справочником значений и с целевой таблицей. Так мы узнаем, новые это данные или нет, что изменилось, соответствуют ли данные справочнику и есть ли дубли.
Универсальный виджет для построчной загрузки данных
Иногда для работы с данными нужна не файловая, а построчная загрузка. Раньше в модальном окне мы накидывали виджеты для ввода: даты, тексты, выпадашки. Для каждой админки у нас был отдельный набор виджетов. Было трудоемко и неудобно. Изучили решение и нашли удобный виджет — JSON-форма. Виджет собирает данные из настроечной таблицы (название колонок, тип и функциональность), готовит форму для ручного ввода со всеми полями и отдает пользователю.
Все доработки позволили нам победить изначальные проблемы, сделать процесс эксплуатации более простым и быстрым и сделать доработку функционала быстрой.
Как еще мы использовали Appsmith.
Интерфейс для связывания нескольких технологий
Решением задачи с CRUD-интерфейсами наш опыт с Appsmith не ограничился.
Например, с его помощью мы создали сервис сверки выдач. Коллегам нужен был инструмент, который позволил бы загружать файлы с данными ID выдач и проводить сверку: есть ли в соответствующей таблице в хранилище такая выдача или нет. В этом кейсе мы использовали Appsmith в качестве интерфейса для взаимодействия с несколькими видами хранилищ.
Через Appsmith пользователи отправляют файлы в объектное хранилище S3 (Yandex Cloud) для последующей загрузки их в БД (Postgres) и запуска процедуры сверки (Pentaho). Результат сверки приходит пользователю на почту, остается только зайти и проверить результат. Весь процесс происходит в фоновом режиме.
Интересности и нюансы
В Appsmith есть нативная интеграция с S3, и при помощи виджета File-picker (для выбора файла пользователем) и нескольких S3 команд можно определить, что мы хотим сделать, в какую папку бакета положить данные и задать условия для скачивания файла.
Нюанс возник, когда мы захотели распарсить эти данные (например в .csv), так как они были в формате base64. Оказалось, что в Appsmith для этого есть штатное решение, так что искать решения на стороне не пришлось.
Использование REST API и внешних JS Библиотек.
Мы хотели узнать, возможно ли сделать CRUD-приложения для нашего инструмента работы с большими данными — Google BigQuery.
Нативной интеграции между инструментами не было, мы изучили вопрос и поняли, что, имея сервисный аккаунт, мы можем воспользоваться REST API: создаем и подписываем токен, отправляем на сервис и, получив авторизационный токен, выполняем запросы в GBQ.
Здесь тоже без нюансов не обошлось. В структуре JWT есть авторизационные данные, которые не меняются, и время действия, ограниченное 60 минутами (начало и окончание периода). Также токен необходимо зашифровать по алгоритму RS256. С генерацией JSON переменных для JWT (Header, Payload и Key) быстро разобрались. Но с шифрованием возникли проблемы. К счастью, в новых версиях Appsmith (начиная с 1.9.х) есть возможность подключать некоторые JS библиотеки и с помощью конструктора вызывать методы из них, чем мы и воспользовались. Это позволило решить проблему автоматической авторизации в GBQ через создание соответствующей JS функции в приложении.
Чего не может Appsmith
Мы изучали кейс, как работать с несколькими средами, когда одно приложения связанно с несколькими базами данных (dev, test,prod), и как вести разработку на тестовой среде, а потом переключаться на продуктовый инстанс. Оказалось, что в бесплатной версии такой возможности нет.
Еще нам не хватает API-интерфейса для управления Appsmith. Такой функционал был бы полезен для настройки сценариев автоматического взаимодействия с сервисом (создание пользователей и выдача прав, импорт/экспорт/редактирование приложений и т.п.).
Но в целом могу еще раз сказать, что в рабочем режиме Appsmith как инструмент нас не разочаровал.