SuperOleg dev notes pinned «Привет! Не так давно на Github была заблокирована организация Тинькофф, и к сожалению публичное зеркало репозитория tramvai со всеми настройками и звездочками кануло в лету. С опозданием переехали в новую организацию - https://github.com/tramvaijs/tramvai…»
Forwarded from Alexey Ryazanov
В 3 версии Tramvai появилась поддержка View Transitions API. Вкратце – это возможность создания анимированных переходов между состояниями DOM. Мы сделали демо на CodeSandbox, показывающую как это работает. Приглашаем ознакомиться.
Возможно, стоит показать это вашим дизайнерам, у них могут возникнуть интересные идеи 🌚
Возможно, стоит показать это вашим дизайнерам, у них могут возникнуть интересные идеи 🌚
tramvai.dev
View Transitions | tramvai
Overview
🔥16👍2
Привет!
Появился интересный проект связанный с микрофронтендами, и хочется рассказать про мои подходы к его проектированию, в первую очередь что бы структурировать их и уложить в голове, выделить проблемные места, но надеюсь что-то будет полезным и вам.
Важный момент - у меня около-нулевой опыт разработки бэкенда и работы с базами данных, поэтому буду особенно рад фидбеку по этим областям.
Сам проект на начало января 2024 года еще на этапе проектирования, поэтому эта серия постов скорее всего часто будет пополняться.
Итак, про проектирование.
Все начинается с проблемы.
Во-первых, у нашего фреймворка Tramvai есть свое решение для микрофронтендов, Child Apps, использование которых только набирает обороты в компании.
Также, в Тинькофф есть еще не меньше 4-х взрослых экосистем с микрофронтендами, про это есть разные доклады и статьи, вот некоторые из них:
- https://www.youtube.com/watch?v=adgUumoPv6o
- https://habr.com/ru/companies/tinkoff/articles/517230/
- https://habr.com/ru/companies/oleg-bunin/articles/718302/
Как минимум в двух из этих экосистем существуют мощные конструкторы страниц на основе микрофронтов-виджетов.
У разных экосистем по большей части разные проблемы, например команде которая начнет использовать наши Child Apps сейчас надо самостоятельно решить и автоматизировать ряд вопросов:
- Версионирование микрофронта
- Публикация статических файлов микрофронта в s3 плюс настроенный CDN
- Управление версиями микрофронтов в приложении (релизы и откаты, история изменений)
- Витрина для отдельных микрофронтов
- Опционально, контракты между микрофронтом и приложением (входящие и исходящие данные, события)
Появился интересный проект связанный с микрофронтендами, и хочется рассказать про мои подходы к его проектированию, в первую очередь что бы структурировать их и уложить в голове, выделить проблемные места, но надеюсь что-то будет полезным и вам.
Важный момент - у меня около-нулевой опыт разработки бэкенда и работы с базами данных, поэтому буду особенно рад фидбеку по этим областям.
Сам проект на начало января 2024 года еще на этапе проектирования, поэтому эта серия постов скорее всего часто будет пополняться.
Итак, про проектирование.
Все начинается с проблемы.
Во-первых, у нашего фреймворка Tramvai есть свое решение для микрофронтендов, Child Apps, использование которых только набирает обороты в компании.
Также, в Тинькофф есть еще не меньше 4-х взрослых экосистем с микрофронтендами, про это есть разные доклады и статьи, вот некоторые из них:
- https://www.youtube.com/watch?v=adgUumoPv6o
- https://habr.com/ru/companies/tinkoff/articles/517230/
- https://habr.com/ru/companies/oleg-bunin/articles/718302/
Как минимум в двух из этих экосистем существуют мощные конструкторы страниц на основе микрофронтов-виджетов.
У разных экосистем по большей части разные проблемы, например команде которая начнет использовать наши Child Apps сейчас надо самостоятельно решить и автоматизировать ряд вопросов:
- Версионирование микрофронта
- Публикация статических файлов микрофронта в s3 плюс настроенный CDN
- Управление версиями микрофронтов в приложении (релизы и откаты, история изменений)
- Витрина для отдельных микрофронтов
- Опционально, контракты между микрофронтом и приложением (входящие и исходящие данные, события)
tramvai.dev
Overview | tramvai
Micro frontends heavily integrated with tramvai framework
👍2🔥2❤1
И тут постепенно появляется идея.
Сначала я разобрал основные слабые места Child Apps, и думал про полноценную экосистему для этих микрофронтов, которая будет решать все значимые проблемы.
А что если пойти дальше, и сделать отдельный сервис - платформу для микрофронтендов, которая будет решать проблемы и других экосистем (эти проблемы обсудим далее)?
Таким образом решение проблемы разделяется на два отдельных эпика:
- Общая платформа для микрофронтов для решения популярных проблем, не зависимая от фреймворков и экосистем
- Доработки специфичные для Child Apps (в ближайших постах не вижу смысла это рассматривать)
Идею платформы я оформил в лонгрид в формате RFC, который сначала обсудил с коллегами внутри команды, доработал и затем расшарил на всех остальных коллег.
RFC детально рассматривает платформу, которая состоит из следующих частей:
- Описание основных процессов (по сути одновременно и функциональные требования)
- Непосредственно сервис - бэкенд и база данных
- UI - админка сервиса (важная часть, так как управление версиями микрофронтов у многих команд либо происходит через коммиты в Gitlab, либо ручное редактирование JSON файлов, оба варианта не удобны по ряду причин)
- CLI утилита - для удобной работы с бэкендом в CI/CD пайплайнах
- Механизм контрактов
- Переиспользуемые CI/CD пайплайны с настроенными процессами
Примеры процессов - публикация новой версии микрофронта на платформе; раскатка новой версии микрофронта в приложении, и так далее.
В работе с этим RFC для себя выделил несколько слабых моментов:
- очень большой контекст, много деталей, RFC сложный для восприятия - стоило разделить RFC с идеей и RFC с детальной реализацией
- дорабатывал идею в процессе написания RFC - пострадала структура
- обсуждал RFC с лидами команд - разработчиков микрофронтов уже после его написания, то есть фактически позже чем нужно начал собирать функциональные требования, которые напрямую влияют на реализацию
Обсуждение экосистем микрофронтов с лидами команд очень помогло сформировать окончательное видение платформы, вдохновиться идеями и собрать доп. требования, а также отделить проблемы специфичные для трамвайных микрофронтов.
Одна из основных общих проблем между экосистемами - это управление версиями микрофронтов в приложениях. На втором месте - валидация контрактов между микрофронтами и приложением - так как независимые от приложения релизы это одна из главных фич микрофронтов, тут очень важна прямая и обратная совместимость.
Сначала я разобрал основные слабые места Child Apps, и думал про полноценную экосистему для этих микрофронтов, которая будет решать все значимые проблемы.
А что если пойти дальше, и сделать отдельный сервис - платформу для микрофронтендов, которая будет решать проблемы и других экосистем (эти проблемы обсудим далее)?
Таким образом решение проблемы разделяется на два отдельных эпика:
- Общая платформа для микрофронтов для решения популярных проблем, не зависимая от фреймворков и экосистем
- Доработки специфичные для Child Apps (в ближайших постах не вижу смысла это рассматривать)
Идею платформы я оформил в лонгрид в формате RFC, который сначала обсудил с коллегами внутри команды, доработал и затем расшарил на всех остальных коллег.
RFC детально рассматривает платформу, которая состоит из следующих частей:
- Описание основных процессов (по сути одновременно и функциональные требования)
- Непосредственно сервис - бэкенд и база данных
- UI - админка сервиса (важная часть, так как управление версиями микрофронтов у многих команд либо происходит через коммиты в Gitlab, либо ручное редактирование JSON файлов, оба варианта не удобны по ряду причин)
- CLI утилита - для удобной работы с бэкендом в CI/CD пайплайнах
- Механизм контрактов
- Переиспользуемые CI/CD пайплайны с настроенными процессами
Примеры процессов - публикация новой версии микрофронта на платформе; раскатка новой версии микрофронта в приложении, и так далее.
В работе с этим RFC для себя выделил несколько слабых моментов:
- очень большой контекст, много деталей, RFC сложный для восприятия - стоило разделить RFC с идеей и RFC с детальной реализацией
- дорабатывал идею в процессе написания RFC - пострадала структура
- обсуждал RFC с лидами команд - разработчиков микрофронтов уже после его написания, то есть фактически позже чем нужно начал собирать функциональные требования, которые напрямую влияют на реализацию
Обсуждение экосистем микрофронтов с лидами команд очень помогло сформировать окончательное видение платформы, вдохновиться идеями и собрать доп. требования, а также отделить проблемы специфичные для трамвайных микрофронтов.
Одна из основных общих проблем между экосистемами - это управление версиями микрофронтов в приложениях. На втором месте - валидация контрактов между микрофронтами и приложением - так как независимые от приложения релизы это одна из главных фич микрофронтов, тут очень важна прямая и обратная совместимость.
👍3🔥2
Проблема обозначена, есть решение, пора приступать к проектированию!
На самом деле рановато, это еще одна проблема моего подхода, работа с требованиями проведена достаточно поверхностно.
Из плюсов - понятны стейкхолдеры, уже есть заинтересованные пользователи, неплохо собраны функциональные требования.
Но не проработаны нефункциональные требования и ограничения. В первую очередь потому что система не предполагает быть сложной или сильно нагруженной, но в будущем лучше формализовать все это заранее.
Немного про инструменты и подходы.
Привычный для меня вайтборд - https://excalidraw.com/
Для проектирования отлично подходить модель C4 - https://c4model.com/, которую на нижнем уровне модели можно комбинировать с UML.
Для схемы БД не стал искать специальные инструменты и использую псевдо-UML.
По модели C4 иду сверху вниз и начинаю с System Context, где указаны:
- пользователи платформы
- сервисы, с которыми платформа взаимодействует (забыл на изображении добавить s3)
Тут все очень просто, но есть важный момент.
Для платформы нужен механизм разграничения доступов, полноценная ролевая модель, которая позволит управлять микрофронтами и приложениями в скоупе отдельных команд.
В нашем Internal Developer Platform сервисе (чуть больше информации про него можно найти у Александра Поломодова - https://t.me/book_cube/1826) уже есть готовые механизмы авторизации, тенантов, групп и ролей, которые идеально подойдут к нашей платформе.
И я очень надеюсь переиспользовать эти механизмы Developer Platform, так как планируется не сложный бэкенд и это упростит разработку в несколько раз)
На самом деле рановато, это еще одна проблема моего подхода, работа с требованиями проведена достаточно поверхностно.
Из плюсов - понятны стейкхолдеры, уже есть заинтересованные пользователи, неплохо собраны функциональные требования.
Но не проработаны нефункциональные требования и ограничения. В первую очередь потому что система не предполагает быть сложной или сильно нагруженной, но в будущем лучше формализовать все это заранее.
Немного про инструменты и подходы.
Привычный для меня вайтборд - https://excalidraw.com/
Для проектирования отлично подходить модель C4 - https://c4model.com/, которую на нижнем уровне модели можно комбинировать с UML.
Для схемы БД не стал искать специальные инструменты и использую псевдо-UML.
По модели C4 иду сверху вниз и начинаю с System Context, где указаны:
- пользователи платформы
- сервисы, с которыми платформа взаимодействует (забыл на изображении добавить s3)
Тут все очень просто, но есть важный момент.
Для платформы нужен механизм разграничения доступов, полноценная ролевая модель, которая позволит управлять микрофронтами и приложениями в скоупе отдельных команд.
В нашем Internal Developer Platform сервисе (чуть больше информации про него можно найти у Александра Поломодова - https://t.me/book_cube/1826) уже есть готовые механизмы авторизации, тенантов, групп и ролей, которые идеально подойдут к нашей платформе.
И я очень надеюсь переиспользовать эти механизмы Developer Platform, так как планируется не сложный бэкенд и это упростит разработку в несколько раз)
Excalidraw
Excalidraw — Collaborative whiteboarding made easy
Excalidraw is a virtual collaborative whiteboard tool that lets you easily sketch diagrams that have a hand-drawn feel to them.
Следующий C4 уровень - Containers.
Тут я уже выделяю составляющие платформы - API, база данных, UI и CLI утилита.
И сторонние сервисы - файловое хранилище s3 и Developer Platform.
За скобками остаются системы для сбора логов, метрик, ошибок, алертов, они подразумеваются но по хорошему стоит их рисовать сразу.
Тут же можно показать и технический стек (фактически описывал я его позже, при проектировании составляющих платформы, на C4 уровнях Components / Code)
API платформы:
- Node.js (писать и поддерживать сервис будут инженеры из Coretech Frontend :) )
- Nest.js (мы любим DI)
-
- Prisma ORM (решит за нас ряд вопросов с БД, например инициализация и миграции)
- aws-sdk (работа с s3)
- prom-client (метрики)
- terminus (health-checks и graceful degradation, обязательно для k8s)
-
UI платформы:
- Tramvai.js (ну вы понимаете)
- Tinkoff UI (наш внутренний React UI-kit, пока еще не в open-source как Taiga)
-
- Клиенты для отправки логов и аналитики во внутренние сервисы
База данных - реляционная (планируется много связей), есть внутренняя DBaaS - PostgreSQL.
А также, для переиспользования в UI и CLI, планируется генерация API клиентов из Swagger схем с помощью любой подходящей библиотеки (например swagger-typescript-api)
Тут я уже выделяю составляющие платформы - API, база данных, UI и CLI утилита.
И сторонние сервисы - файловое хранилище s3 и Developer Platform.
За скобками остаются системы для сбора логов, метрик, ошибок, алертов, они подразумеваются но по хорошему стоит их рисовать сразу.
Тут же можно показать и технический стек (фактически описывал я его позже, при проектировании составляющих платформы, на C4 уровнях Components / Code)
API платформы:
- Node.js (писать и поддерживать сервис будут инженеры из Coretech Frontend :) )
- Nest.js (мы любим DI)
-
@nestjs/swagger
- Prisma ORM (решит за нас ряд вопросов с БД, например инициализация и миграции)
- aws-sdk (работа с s3)
- prom-client (метрики)
- terminus (health-checks и graceful degradation, обязательно для k8s)
-
@opentelemetry/sdk-node
(трейсинг)UI платформы:
- Tramvai.js (ну вы понимаете)
- Tinkoff UI (наш внутренний React UI-kit, пока еще не в open-source как Taiga)
-
@micro-sentry/browser
(наша open-source либа для отправки ошибок в Sentry и подобные сервисы)- Клиенты для отправки логов и аналитики во внутренние сервисы
База данных - реляционная (планируется много связей), есть внутренняя DBaaS - PostgreSQL.
А также, для переиспользования в UI и CLI, планируется генерация API клиентов из Swagger схем с помощью любой подходящей библиотеки (например swagger-typescript-api)
👌1
Привет! Продолжаем рубрику проектирование на диване.
Детально проектировать сервис я решил начиная со схемы базы данных, и это очень помогло для проектирования бэкенда и в целом улучшения изначальных идей из RFC.
В первую очередь выделил сущности:
- Microfront - каждый уникальный микрофронтенд
- Application - для группировки необходимых микрофронтов конкретных версий
- Contract - абстрактная сущность, должна быть совместима у микрофронта и приложения
Тут немного отвлекусь про контракты.
Уже писал, что нужен максимально независимый от технологий механизм. И тут нам на помощь приходит SemVer!
Для контракта достаточно иметь уникальное имя и версионирование по SemVer, таким образом имея версии контрактов у приложения и используемых на нем микрофронтов, мы легко можем провалидировать совместимость по семверу, не вникая в нюансы реализации (как правило это npm пакет с TS интерфейсами или даже конкретными объектами).
Нам критична история изменений, и появляются новые сущности:
- History - представляет собой состояние Application в конкретный момент времени (предполагается что пачку изменений в UI можно сгруппировать в одну запись в историю)
- Mapping - связь между приложением, микрофронтом конкретной версии и конкретной записью в истории
Также выделил версии микрофронтов и контрактов в отдельные таблицы, это позволяет им иметь разные метаданные, и при этом быть связанными общими сущностями:
- MicrofrontVersion
- ContractVersion
В эту схему позже был добавлен механизм пресетов - например, если разработчик хочет делать canary релизы, можно собрать два маппинга для одного приложения, а уже на уровне приложения использовать нужный конфиг.
Детально проектировать сервис я решил начиная со схемы базы данных, и это очень помогло для проектирования бэкенда и в целом улучшения изначальных идей из RFC.
В первую очередь выделил сущности:
- Microfront - каждый уникальный микрофронтенд
- Application - для группировки необходимых микрофронтов конкретных версий
- Contract - абстрактная сущность, должна быть совместима у микрофронта и приложения
Тут немного отвлекусь про контракты.
Уже писал, что нужен максимально независимый от технологий механизм. И тут нам на помощь приходит SemVer!
Для контракта достаточно иметь уникальное имя и версионирование по SemVer, таким образом имея версии контрактов у приложения и используемых на нем микрофронтов, мы легко можем провалидировать совместимость по семверу, не вникая в нюансы реализации (как правило это npm пакет с TS интерфейсами или даже конкретными объектами).
Нам критична история изменений, и появляются новые сущности:
- History - представляет собой состояние Application в конкретный момент времени (предполагается что пачку изменений в UI можно сгруппировать в одну запись в историю)
- Mapping - связь между приложением, микрофронтом конкретной версии и конкретной записью в истории
Также выделил версии микрофронтов и контрактов в отдельные таблицы, это позволяет им иметь разные метаданные, и при этом быть связанными общими сущностями:
- MicrofrontVersion
- ContractVersion
В эту схему позже был добавлен механизм пресетов - например, если разработчик хочет делать canary релизы, можно собрать два маппинга для одного приложения, а уже на уровне приложения использовать нужный конфиг.
👍3
Далее, переходим к бэкенду.
Сначала поверхностно, уровень C4 components.
Как уже писал, это не самый сложный бэкенд и не тот случай когда когда нам нужны DDD или Hexagonal Architecture.
В первую очередь хочется отделить бизнес-логику от работы с запросами.
Также, выделить предметную область - сущности которыми будет оперировать бэкенд для удобства будут отличаться от сущностей, которые мы создали в базе данных.
Также у нас будут сервисы для работы с внешними хранилищами.
Итого слои приложения:
- Controllers - минимум логики, обработка API роутов, работа с req/res
- Services - конкретный функционал, без прямой работы с БД
- Entities - схема сущностей API
- Storages:
- Prisma - схема сущностей в БД, работа с БД, миграции
- s3 - работа с s3
Из важных границ, стоит для работы с БД сделать абстрактный интерфейс, а адаптером для этого интерфейса будет Prisma сервис - это немного ослабит зависимость от конкретной ORM.
И если все-таки мы в итоге возьмем Prisma (от вас много комментариев по этому поводу :) ), хочется переиспользовать опыт работы с Redux селекторами и React-Query, и выделить дополнительный слой с атомарными и переиспользуемыми queries, которые можно будет комбинировать уровнем выше, в том числе в транзакции.
Пока не прорабатываем логику авторизации / пользователей / ролей и групп - как уже писал тут хочется переиспользовать API нашей IDP.
Сначала поверхностно, уровень C4 components.
Как уже писал, это не самый сложный бэкенд и не тот случай когда когда нам нужны DDD или Hexagonal Architecture.
В первую очередь хочется отделить бизнес-логику от работы с запросами.
Также, выделить предметную область - сущности которыми будет оперировать бэкенд для удобства будут отличаться от сущностей, которые мы создали в базе данных.
Также у нас будут сервисы для работы с внешними хранилищами.
Итого слои приложения:
- Controllers - минимум логики, обработка API роутов, работа с req/res
- Services - конкретный функционал, без прямой работы с БД
- Entities - схема сущностей API
- Storages:
- Prisma - схема сущностей в БД, работа с БД, миграции
- s3 - работа с s3
Из важных границ, стоит для работы с БД сделать абстрактный интерфейс, а адаптером для этого интерфейса будет Prisma сервис - это немного ослабит зависимость от конкретной ORM.
И если все-таки мы в итоге возьмем Prisma (от вас много комментариев по этому поводу :) ), хочется переиспользовать опыт работы с Redux селекторами и React-Query, и выделить дополнительный слой с атомарными и переиспользуемыми queries, которые можно будет комбинировать уровнем выше, в том числе в транзакции.
Пока не прорабатываем логику авторизации / пользователей / ролей и групп - как уже писал тут хочется переиспользовать API нашей IDP.
👍1
Нижний уровень C4 - Code.
Но у нас осталось много не проработанных вещей, поэтому дальше я работаю сразу над несколькими:
- сущности бэкенда
- структура API роутов
- основные классы и методы
- описание сценариев работы
Список сущностей похож на БД, но собран в удобные для дальнейшего использования объекты.
API роуты старался делать не слишком низкоуровневыми, а под основные кейсы использования.
Например, у каждого приложения могут быть пресеты, в каждом свой маппинг микрофронтов.
Сначала я описал эндпоинты вида
Для основных классов из C4 Components описал методы и логику их работы. Вообще, получилось что эти сервисы и их методы 1 к 1 соотносятся с API эндпоинтами, и кажется это не очень корректно, но может измениться после рефакторинга - далее планирую найти и вынести общую логику из сервисов.
И конкретный пример:
Есть сервис
Для метода rollback описана логика работы:
- В рамках одной транзакции, получаем в БД соответствующую запись History либо берем предыдущую
- Находим все записи History с timestamp выше, проходим по ним
- В цикле, в таблице Mapping находим все записи под текущие History и Application
- Удаляем эти записи Mapping, в конце удаляем эту запись History
- И наконец обновляем поле Revision для текущей записи Application
На этом этапе много сложностей, так как буквально зайти дальше - это уже писать код, держать все в голове и прорабатывать низкоуровневые моменты оказалось сложнее всего, особенно в областях с множеством неизвестных.
Из интересного, сильно задумался над процессом загрузки файлов микрофронта через API платформы в файловое хранилище s3.
План примерно такой:
- CLI утилита в CI/CD создает объект FormData, считывает контент файлов, добавляет туда и отправляет стрим на бэкенд
- Бэкенд не буферизует эти данные, а сразу перенаправляет стрим в s3 через aws-sdk
Тут стоит сделать отдельно прототип и убедиться что нет подводных камней.
Но у нас осталось много не проработанных вещей, поэтому дальше я работаю сразу над несколькими:
- сущности бэкенда
- структура API роутов
- основные классы и методы
- описание сценариев работы
Список сущностей похож на БД, но собран в удобные для дальнейшего использования объекты.
API роуты старался делать не слишком низкоуровневыми, а под основные кейсы использования.
Например, у каждого приложения могут быть пресеты, в каждом свой маппинг микрофронтов.
Сначала я описал эндпоинты вида
/:tenant/:app/:preset/mapping
где работа с сущностью Mapping
, но понял что по отдельности они не нужны, и удобнее сразу работать со всеми маппингами - например на GET /:tenant/:app/mapping
возвращать Record<Preset, Mapping>
.Для основных классов из C4 Components описал методы и логику их работы. Вообще, получилось что эти сервисы и их методы 1 к 1 соотносятся с API эндпоинтами, и кажется это не очень корректно, но может измениться после рефакторинга - далее планирую найти и вынести общую логику из сервисов.
И конкретный пример:
Есть сервис
HistoryService
, сигнатура одного из его методов - rollback( Tenant, Application, History? ): History[]
- он будет использоваться для откатов по истории изменения маппингов.Для метода rollback описана логика работы:
- В рамках одной транзакции, получаем в БД соответствующую запись History либо берем предыдущую
- Находим все записи History с timestamp выше, проходим по ним
- В цикле, в таблице Mapping находим все записи под текущие History и Application
- Удаляем эти записи Mapping, в конце удаляем эту запись History
- И наконец обновляем поле Revision для текущей записи Application
На этом этапе много сложностей, так как буквально зайти дальше - это уже писать код, держать все в голове и прорабатывать низкоуровневые моменты оказалось сложнее всего, особенно в областях с множеством неизвестных.
Из интересного, сильно задумался над процессом загрузки файлов микрофронта через API платформы в файловое хранилище s3.
План примерно такой:
- CLI утилита в CI/CD создает объект FormData, считывает контент файлов, добавляет туда и отправляет стрим на бэкенд
- Бэкенд не буферизует эти данные, а сразу перенаправляет стрим в s3 через aws-sdk
Тут стоит сделать отдельно прототип и убедиться что нет подводных камней.
Привет!
Вернулся из отпуска, вхожу в привычный ритм, пора начинать писать)
По проектированию Microfrontends Platform я не успел рассмотреть клиентскую архитектуру, но думаю тут достаточно информации из одного из старых постов - https://t.me/super_oleg_dev/41, те же подходы планируем применять и для UI сервиса.
Детальное проектирование сервиса очень помогло для старта, многие базовые сущности оказались достаточно гибкими и расширяемыми, и остались без изменений.
При этом, дизайн все-равно быстро устаревает по ряду причин:
- выявляются новые потребности
- все это время идет постоянная проработка сценариев и граничных кейсов
- информация мигрирует в другие источники
Потребности.
Как я писал ранее, одно из слабых мест проекта это предварительный сбор требований. За одну-две встречи и презентовать свое видение проекта заинтересованным лицам, и собрать с них все потребности кажется невозможно.
В итоге, кейсы использования сервиса у основного заказчика требуют совсем другого взгляда на возможности проекта - основная разница, что версиями и доставкой микрофронтов управляют не разработчики приложений где они используются (как я планировал изначально), а разработчики самих микрофронтов, которым грубо говоря нужно релизить большие наборы протестированных микрофронтов, часто, и сразу на все приложения где они используются.
Это очень сильно влияет на сценарии использования сервиса, и требуемый функционал, можно сказать у нас получается x2 фич.
И одновременно почти не влияет на структуру базы данных (расширяет в первую очередь), где в основе по прежнему штучные релизы микрофронтов, привязанные к конкретным приложениям.
Поэтому в будущем для любых проектов я планирую уделять намного больше времени на сбор требований и формирование сценариев использования.
Проработка сценариев и граничные кейсы.
Пока это похоже на потенциально бесконечный процесс, так как он идет рука об руку с развитием продукта.
Но на первых этапах это конечно проработка основного функционала, даже на самые простые кейсы можно добавить десяток правил валидации, а на более сложные - очень повезет если получится найти все подводные камни до реализации.
Пример, есть потребность - массовые релизы микрофронтов.
Коллегам нужна возможность группировать микрофронты, релизить группу на несколько приложений одновременно, откатывать эти релизы, при этом не затрагивая другие микрофронты приложения.
Сюда добавляются такие кейсы как “заморозка” версии одного микрофронта из группы, если следующие версии сломаны, но не хотим блокировать релизы полностью.
Потом встает вопрос изменения состава групп, перенос микрофронтов между ними, и так далее.
Что бы не утонуть в этой сложности, проводим регулярные встречи и ведем подробную документацию.
Для MVP проекта сильно ограничили функционал, и прикинули следующие итерации самых приоритетных вещей.
Сложные кейсы стараемся упрощать и откладывать проработку, если есть понимание что возможное решение не потребует перелопатить всю архитектуру проекта в будущем.
Источники информации.
Вайтборд почти полностью устраивал меня на начальных этапах проектирования.
Но для долгоживущей информации, которая должна быть полной и актуальной, не обойтись без какой-либо wiki.
Что у нас уже есть в этой документации:
- минимальный глоссарий (выбрать и согласовать общие и понятные для всех термины тоже оказалась целая история!)
- сценарии использования сервиса
- потребности стейкхолдеров
- значимые архитектурные решения
- процессы разработки и приемки фичей заказчиками
- спецификация как пишем API эндпоинты
- всевозможные meeting notes
Ряд вещей перемещается в кодовую базу:
- схема базы данных - Prisma
- схема API эндпоинтов - Open API
- всевозможные сценарии - Allure тест кейсы
Тут важно иметь один обновляемый источник информации, постепенно уйти от дублирования, соответственно этот источник должен быть удобен в поддержке.
Вернулся из отпуска, вхожу в привычный ритм, пора начинать писать)
По проектированию Microfrontends Platform я не успел рассмотреть клиентскую архитектуру, но думаю тут достаточно информации из одного из старых постов - https://t.me/super_oleg_dev/41, те же подходы планируем применять и для UI сервиса.
Детальное проектирование сервиса очень помогло для старта, многие базовые сущности оказались достаточно гибкими и расширяемыми, и остались без изменений.
При этом, дизайн все-равно быстро устаревает по ряду причин:
- выявляются новые потребности
- все это время идет постоянная проработка сценариев и граничных кейсов
- информация мигрирует в другие источники
Потребности.
Как я писал ранее, одно из слабых мест проекта это предварительный сбор требований. За одну-две встречи и презентовать свое видение проекта заинтересованным лицам, и собрать с них все потребности кажется невозможно.
В итоге, кейсы использования сервиса у основного заказчика требуют совсем другого взгляда на возможности проекта - основная разница, что версиями и доставкой микрофронтов управляют не разработчики приложений где они используются (как я планировал изначально), а разработчики самих микрофронтов, которым грубо говоря нужно релизить большие наборы протестированных микрофронтов, часто, и сразу на все приложения где они используются.
Это очень сильно влияет на сценарии использования сервиса, и требуемый функционал, можно сказать у нас получается x2 фич.
И одновременно почти не влияет на структуру базы данных (расширяет в первую очередь), где в основе по прежнему штучные релизы микрофронтов, привязанные к конкретным приложениям.
Поэтому в будущем для любых проектов я планирую уделять намного больше времени на сбор требований и формирование сценариев использования.
Проработка сценариев и граничные кейсы.
Пока это похоже на потенциально бесконечный процесс, так как он идет рука об руку с развитием продукта.
Но на первых этапах это конечно проработка основного функционала, даже на самые простые кейсы можно добавить десяток правил валидации, а на более сложные - очень повезет если получится найти все подводные камни до реализации.
Пример, есть потребность - массовые релизы микрофронтов.
Коллегам нужна возможность группировать микрофронты, релизить группу на несколько приложений одновременно, откатывать эти релизы, при этом не затрагивая другие микрофронты приложения.
Сюда добавляются такие кейсы как “заморозка” версии одного микрофронта из группы, если следующие версии сломаны, но не хотим блокировать релизы полностью.
Потом встает вопрос изменения состава групп, перенос микрофронтов между ними, и так далее.
Что бы не утонуть в этой сложности, проводим регулярные встречи и ведем подробную документацию.
Для MVP проекта сильно ограничили функционал, и прикинули следующие итерации самых приоритетных вещей.
Сложные кейсы стараемся упрощать и откладывать проработку, если есть понимание что возможное решение не потребует перелопатить всю архитектуру проекта в будущем.
Источники информации.
Вайтборд почти полностью устраивал меня на начальных этапах проектирования.
Но для долгоживущей информации, которая должна быть полной и актуальной, не обойтись без какой-либо wiki.
Что у нас уже есть в этой документации:
- минимальный глоссарий (выбрать и согласовать общие и понятные для всех термины тоже оказалась целая история!)
- сценарии использования сервиса
- потребности стейкхолдеров
- значимые архитектурные решения
- процессы разработки и приемки фичей заказчиками
- спецификация как пишем API эндпоинты
- всевозможные meeting notes
Ряд вещей перемещается в кодовую базу:
- схема базы данных - Prisma
- схема API эндпоинтов - Open API
- всевозможные сценарии - Allure тест кейсы
Тут важно иметь один обновляемый источник информации, постепенно уйти от дублирования, соответственно этот источник должен быть удобен в поддержке.
Telegram
SuperOleg dev notes
Другая задача - разработка рекомендаций и практических советов по организации структуры и архитектуры в tramvai приложениях.
Нашей команде кажется очень перспективным подход Feature Sliced - https://feature-sliced.design/
В рамках исследования подготовил…
Нашей команде кажется очень перспективным подход Feature Sliced - https://feature-sliced.design/
В рамках исследования подготовил…
👍4👎1
Про разработку.
Запланированные процессы такие:
- один разработчик пишет бэк, один фронт- до разработки, создается задача на конкретный небольшой функционал
- бэк пишет Open API схему и тест кейсы до реализации, на этом этапе асинхронно ревью/приемка заказчиком
- фронт накидывает мокапы и тест кейсы до реализации, на этом этапе асинхронно ревью/приемка заказчиком
- фронт получает сгенерированные API клиенты + моки от бэка до реализации
- реализация обязательно с тестами (Mostly integration!)
И если с тестами нам очень помогают коллеги, в том числе QA-инженер (отсутствует в нашей команде), сильно недооценили работу по дизайну, делать хорошие мокапы сложно даже при наличии кита и каких-то гайдлайнов, поэтому в асинхронном режиме будем привлекать дизайнера (отсутствует в нашей команде).
Также, большой объем работы потребовался на изначальную настройку инфраструктуры, это и тестовое окружение, Allure, генераторы клиентов и моков, CI/CD, и многое другое.
Поэтому процессы еще совсем не прошли проверку временем.
История далека от завершения, но очень надеюсь в следующих постах затронуть сторонние темы, и возвращаться тут к MF Platform по мере возникновения интересных инсайтов, точно будет что рассказать по SRE (платформу будут использовать критичные сервисы, что подразумевает высокие требования к доступности и поддержке).
Запланированные процессы такие:
- один разработчик пишет бэк, один фронт- до разработки, создается задача на конкретный небольшой функционал
- бэк пишет Open API схему и тест кейсы до реализации, на этом этапе асинхронно ревью/приемка заказчиком
- фронт накидывает мокапы и тест кейсы до реализации, на этом этапе асинхронно ревью/приемка заказчиком
- фронт получает сгенерированные API клиенты + моки от бэка до реализации
- реализация обязательно с тестами (Mostly integration!)
И если с тестами нам очень помогают коллеги, в том числе QA-инженер (отсутствует в нашей команде), сильно недооценили работу по дизайну, делать хорошие мокапы сложно даже при наличии кита и каких-то гайдлайнов, поэтому в асинхронном режиме будем привлекать дизайнера (отсутствует в нашей команде).
Также, большой объем работы потребовался на изначальную настройку инфраструктуры, это и тестовое окружение, Allure, генераторы клиентов и моков, CI/CD, и многое другое.
Поэтому процессы еще совсем не прошли проверку временем.
История далека от завершения, но очень надеюсь в следующих постах затронуть сторонние темы, и возвращаться тут к MF Platform по мере возникновения интересных инсайтов, точно будет что рассказать по SRE (платформу будут использовать критичные сервисы, что подразумевает высокие требования к доступности и поддержке).
👍7❤1🤔1
Про deferred экшены и стриминг, которые анонсировал для трамвая тут - https://t.me/super_oleg_dev/136
После нескольких неудачных релизов на прод на одном из приложений Тинькофф Путешествия, продолжаем активно дорабатывать фичу, собрал несколько интересных моментов, о которых хочется рассказать.
Фичу очень хочется в прод - радикально улучшает метрики производительности - и общую LCP, и кастомную в приложении, которая как раз показывает как скоро нужный блок был показан в приложении, примерно на полторы секунды на 50м перцентиле.
В самом начале мы столкнулись ещё на тестовом стенде с проблемой буферизации.
Весь смысл стриминга HTML - отдать как можно раньше первый байт ответа на клиент, и все статичные элементы разметки.
При этом по дефолту, балансеры, в нашем случае Nginx - буферизуют ответ от апстрима, что бы не держать слишком много долгих открытых соединений, что полезно в большинстве случаев, но не для стриминга, где это напрямую ухудшает TTFB.
Отключить можно на балансере:
proxy_request_buffering off;
Или через HTTP заголовок в ответе на запрос за страницей:
X-Accel-Buffering: no
Также важно, что бы тайм-аут ответа от апстрима на балансере был выше, чем ваш максимальный тайм-аут на стриминг в приложении - иначе пользователь просто не получит кусок разметки.
В доке Next.js или Marko.js можно найти полезную информацию по теме:
- https://markojs.com/docs/troubleshooting-streaming/
- https://nextjs.org/docs/app/building-your-application/deploying#streaming-and-suspense
После нескольких неудачных релизов на прод на одном из приложений Тинькофф Путешествия, продолжаем активно дорабатывать фичу, собрал несколько интересных моментов, о которых хочется рассказать.
Фичу очень хочется в прод - радикально улучшает метрики производительности - и общую LCP, и кастомную в приложении, которая как раз показывает как скоро нужный блок был показан в приложении, примерно на полторы секунды на 50м перцентиле.
В самом начале мы столкнулись ещё на тестовом стенде с проблемой буферизации.
Весь смысл стриминга HTML - отдать как можно раньше первый байт ответа на клиент, и все статичные элементы разметки.
При этом по дефолту, балансеры, в нашем случае Nginx - буферизуют ответ от апстрима, что бы не держать слишком много долгих открытых соединений, что полезно в большинстве случаев, но не для стриминга, где это напрямую ухудшает TTFB.
Отключить можно на балансере:
proxy_request_buffering off;
Или через HTTP заголовок в ответе на запрос за страницей:
X-Accel-Buffering: no
Также важно, что бы тайм-аут ответа от апстрима на балансере был выше, чем ваш максимальный тайм-аут на стриминг в приложении - иначе пользователь просто не получит кусок разметки.
В доке Next.js или Marko.js можно найти полезную информацию по теме:
- https://markojs.com/docs/troubleshooting-streaming/
- https://nextjs.org/docs/app/building-your-application/deploying#streaming-and-suspense
Telegram
SuperOleg dev notes
Привет!
Релизнули экспериментальный функционал с Deferred экшенами.
Сделал темплейт где можно потыкать результат - https://codesandbox.io/p/sandbox/tramvai-deferred-actions-s95q62
Экшен выполняется 1 секунду, время рендера компонента который зависит от…
Релизнули экспериментальный функционал с Deferred экшенами.
Сделал темплейт где можно потыкать результат - https://codesandbox.io/p/sandbox/tramvai-deferred-actions-s95q62
Экшен выполняется 1 секунду, время рендера компонента который зависит от…
👍6
Отдельный челлендж - это продать преимущества стриминга вашим SRE :)
Далее пойдут более специфичные кейсы.
Приложение используется в основном в вебвью, и в основном в мобильном приложении Тинькофф на IOS.
Как вы понимаете, именно у этого сегмента возникли проблемы.
Все симптомы указывают на то, что вебвью перестает ждать окончания ответа и просто обрывает стрим, пользователь остаётся с незаконченной HTMLкой.
Дебажить вебвью сложно, пробовали разное, долго, коллега уже начал локально собирать нативное приложение и шатать его кодовую базу. И нашел!
Оказалось, что проблема возникает, с непонятной периодичностью, когда веб приложение в вебвью дёргает нативный экшен что бы скрыть лоадер нативного приложения, когда веб приложение загрузилось.
До сих пор не понимаем в чем причина, но сложился паззл с другим кейсом - когда у коллег по непонятной логике отваливались один или несколько запросов на старте вебвью - вебвью просто рубил всю не завершенные сетевые запросы, в том числе и за документом.
Пишите, если сталкивались или знаете статьи по теме.
Далее пойдут более специфичные кейсы.
Приложение используется в основном в вебвью, и в основном в мобильном приложении Тинькофф на IOS.
Как вы понимаете, именно у этого сегмента возникли проблемы.
Все симптомы указывают на то, что вебвью перестает ждать окончания ответа и просто обрывает стрим, пользователь остаётся с незаконченной HTMLкой.
Дебажить вебвью сложно, пробовали разное, долго, коллега уже начал локально собирать нативное приложение и шатать его кодовую базу. И нашел!
Оказалось, что проблема возникает, с непонятной периодичностью, когда веб приложение в вебвью дёргает нативный экшен что бы скрыть лоадер нативного приложения, когда веб приложение загрузилось.
До сих пор не понимаем в чем причина, но сложился паззл с другим кейсом - когда у коллег по непонятной логике отваливались один или несколько запросов на старте вебвью - вебвью просто рубил всю не завершенные сетевые запросы, в том числе и за документом.
Пишите, если сталкивались или знаете статьи по теме.
❤2👍1