Fuse: каталог сценариев поверх чужих программных интерфейсов, или что делать, когда "просто дёрни ручку" - это не просто
Всем привет. Мы - небольшая команда, и последние несколько недель мы строили Fuse: платформу, где из любых открытых программных интерфейсов можно собрать готовый сценарий и выложить его в каталог, чтобы им пользовался человек, который слова "программный интерфейс" никогда не слышал. В этом посте расскажу, зачем мы это делаем, как оно устроено внутри, и попрошу у вас обратной связи - проект на той стадии, когда критика полезнее похвалы.
Боль, с которой всё началось
Ситуация, знакомая, наверное, каждому, кто работал в компании крупнее пяти человек. Приходит коллега из соседнего отдела: "Слушай, а можно как-то распознать вот эти сканы? Я видел, у сервиса X есть API". Можно. Нужно зарегистрироваться, получить ключ, прочитать документацию, понять, что распознавание там асинхронное - сначала загружаешь файл, потом опрашиваешь статус, потом забираешь результат. Написать скрипт. Отдать коллеге. Через неделю скрипт сломался, потому что коллега запустил его не с той версией питона.
И так каждый раз. API-сервисов вокруг сотни - распознавание документов, синтез речи, проверка контрагентов, геокодинг, что угодно. Но между "у сервиса есть API" и "обычный человек получил результат" лежит пропасть: кто-то должен написать обвязку, где-то её захостить, как-то дать к ней доступ.
Zapier и n8n эту пропасть частично закрывают, но они про автоматизацию для себя: собрал пайплайн - сам им и пользуешься. А нам хотелось другого: чтобы один человек (разработчик, интегратор, да хоть сам провайдер API) собрал сценарий один раз, а дальше им пользовались все. Через обычную веб-страницу, с формой, кнопкой "Запустить" и прогресс-баром.
Так появился Fuse.
Что это такое
Если коротко, Fuse - это три вещи в одном:
- Импорт API. Загружаешь OpenAPI-спеку сервиса - и все его эндпоинты становятся "кубиками", из которых можно собирать сценарии.
- Конструктор сценариев. Визуальный редактор, где выстраиваешь цепочку шагов: вызов эндпоинта, задержка, опрос статуса, вложенный сценарий, пользовательская страница. Выходы одного шага маппятся на входы следующего.
- Маркетплейс. Готовый сценарий публикуется как карточка с описанием, категорией и счётчиком запусков. Любой пользователь находит её через каталог или поиск, жмёт "Запустить" - и просто заполняет форму.
Ключевая идея в том, что конечный пользователь не видит ни JSON, ни токены, ни устройство пайплайна. Он видит страницу: "загрузите файл", "нажмите кнопку", "вот ваш результат".
Как выглядит запуск глазами пользователя
Пользователь открывает карточку сценария - она публичная, можно посмотреть шаги и список задействованных сервисов ещё до регистрации. Нажимает "Запустить" (тут уже нужен вход, у нас OAuth через Яндекс). Дальше сценарий выполняется по шагам, и весь прогресс прилетает в браузер в реальном времени через WebSocket: какой шаг выполняется, сколько прошло, где ошибка, если она случилась.
Самое интересное - шаги типа "Страница". Это пользовательские экраны прямо внутри выполнения сценария. Автор сценария собирает их в отдельном конструкторе: сетка на 6 колонок, drag-and-drop блоков - поля ввода, селекты, дропзона для файлов, текст. Блоки ввода становятся выходами шага (то, что ввёл пользователь, уходит дальше по цепочке), блоки отображения показывают результаты уже пройденных шагов. Когда выполнение доходит до такого шага, сценарий встаёт на паузу и ждёт, пока пользователь заполнит форму.
Из таких страниц можно собрать и финальный экран результата - например, отрендерить итоговый markdown-отчёт в конце сценария.
Если сценарий длинный (например, распознавание большого документа), закрывать вкладку не страшно: запуск живёт на сервере, история запусков доступна в личном кабинете, а по завершении приходит уведомление. Файловые результаты складываются в хранилище и доступны из истории.
Как выглядит создание сценария
Автор начинает с приложения - так мы называем подключённый API-сервис. Загрузил OpenAPI-спеку, получил список эндпоинтов, сгруппированный по тегам, с поиском по методу, пути и описанию.
Дальше - сценарий. Пять типов шагов:
- Endpoint API - обычный вызов метода. Path/Query/Header/Body параметры разбираются из схемы, для каждого можно задать значение руками или примапить выход предыдущего шага. Если у эндпоинта файловый вход - файл прилетает из дропзоны на пользовательской странице, причём загрузка сама выбирает режим: маленькие файлы одним запросом, большие - чанками с паузой и возобновлением.
- Периодический запрос - тот же вызов, но повторяемый с интервалом до признака завершения. Классика для асинхронных API: "загрузи документ, потом опрашивай статус, пока не будет done".
- Задержка - пауза между шагами.
- Страница - тот самый пользовательский экран.
- Другой сценарий - вложение готового сценария целиком. Циклические вложения система не даст создать.
Маппинг данных между шагами - центральная часть конструктора: у каждого шага есть выходы (поля из схемы ответа), и любой из них можно подставить во вход любого следующего шага.
Когда сценарий готов - заполняешь карточку (обложка, rich-text описание, категория) и публикуешь. Всё, он в каталоге.
Под капотом
Пара слов о технической части, куда же без неё.
- Фронтенд - Nuxt 3 (SSR), Pinia, Tailwind. Дизайн-система своя - набор Vue-компонентов поверх общих токенов.
- Бэкенд - NestJS: REST API, WebSocket-шлюз на Socket.IO и воркер исполнения сценариев.
- Очередь - AWS SQS: запуск сценария кладётся в очередь, consumer забирает и исполняет шаги. Для локальной разработки - LocalStack, так что вся инфраструктура поднимается docker-compose'ом.
- Хранилище - MongoDB для данных, S3-совместимое (MinIO локально) для файлов: аватарки, загруженные файлы, артефакты запусков.
- Монорепа - pnpm workspaces + Turborepo, общие типы вынесены в shared-пакет.
Отдельно упомяну, что весь проект мы ведём через spec-driven подход: каждая фича сначала описывается спекой с требованиями и сценариями (используем OpenSpec), потом реализуется и проверяется против спеки. На маленькой команде это неожиданно хорошо зашло - спеки заменяют и ТЗ, и часть документации.
Из интересных мелочей исполнения: при подключении клиента к запуску сервер сразу отдаёт снапшот текущего состояния, а не только новые события. Поэтому если запуск отработал за миллисекунды - быстрее, чем браузер успел открыть сокет - пользователь всё равно увидит результат, а не вечное "Выполняем сценарий...". На эти грабли мы наступили сами и теперь предупреждаем других.
Кому это нужно
Мы видим три аудитории:
- Провайдеры API. Для них Fuse - витрина: вместо "вот документация, разбирайтесь" можно выложить готовые сценарии использования своего API, которые потенциальный клиент попробует за минуту без единой строчки кода.
- Интеграторы и разработчики. Собрал сценарий из двух-трёх сервисов - отдал заказчику ссылку. Не нужно хостить обвязку и городить UI.
- Конечные пользователи - те самые коллеги из соседнего отдела. Им вообще ничего не нужно знать про API: каталог, поиск, кнопка "Запустить", форма.
Помогите нам
Проект в активной разработке, и сейчас нам важнее всего проверить гипотезы и понять: будет ли это работать и действительно ли это нужно людям. Что особенно интересно:
- Сама идея маркетплейса сценариев - видите ли вы ей применение у себя в организации? Или ниша уже закрыта Zapier/n8n/Альбато и разница "для себя vs для других" надуманная?
- Модель шага "Страница" - насколько понятна идея пользовательских экранов внутри сценария? Каких блоков не хватает в первую очередь?
- Опыт автора сценария - если вы работали с OpenAPI-спеками: чего вам не хватило бы в таком конструкторе? Авторизация к сторонним API, окружения (dev/prod), версионирование сценариев - что из этого критично для MVP?
- Технические решения - welcome в комментарии, если видите проблемы в архитектуре. Особенно интересны мнения про исполнение через очередь с ожиданием пользовательского ввода посреди запуска. Также хотелось бы узнать про лучшие практики масштабирования воркеров на одновременное исполнение тысяч сценариев
Если у вас есть API, который вы хотели бы обернуть в сценарий, или боль, которую такая штука могла бы закрыть - расскажите в комментариях, это для нас сейчас самое ценное.
P.S: на текущий момент проект MIT и его можно запустить самому. Только дергайте ветку develop