Главная> Кейсы> Эталонная архитектура кроссплатформенного сервисного приложения

Эталонная архитектура кроссплатформенного сервисного приложения

Тип референсаСправочное описание приложения
Материалы для ознакомленияFlutter · Dart · Go · PostgreSQL · Redis · FCM/APNs
Эталонная архитектура кроссплатформенного сервисного приложения

Справочная информация о приложении. Это иллюстративная архитектура и контрольный список объёма работ, а не проверенный проект клиента или результат измеренного внедрения. Технологии, объём интеграции и результаты поставки согласовываются для конкретного технического задания.

Сценарий и ограничения

Сервисный продукт, в котором iOS и Android используют одинаковые рабочие процессы, а небольшой команде необходимо поддерживать обе платформы. Архитектуру определяют три ограничения: ненадёжные мобильные сети, циклы проверки в магазинах приложений, из-за которых выпуск срочных исправлений занимает много времени, и необходимость изменять бизнес-правила без выпуска новой сборки.

Архитектура

Слои и зоны ответственности

СлойТехнологияЗона ответственности
ПриложениеFlutter (Dart), разделённый на UI / состояние / репозиторийЭкраны и взаимодействие. Слой репозитория — единственный компонент, который знает, поступили ли данные из сети или из локального кэша, поэтому обработка автономной работы не попадает в код UI.
Локальное хранилищеSQLite (drift) + защищённое хранилище платформыКэшированные сущности, очередь ожидающих записи операций и токены в защищённом хранилище вместо shared preferences.
APIGo + Gin, версионируемые маршрутыБизнес-правила, валидация, авторизация. Версионирование с первого дня необходимо, поскольку старые сборки приложения остаются у пользователей ещё долго после выпуска.
ХранилищеPostgreSQLТранзакционные данные; JSONB используется для действительно переменных атрибутов вместо бесконечного расширения таблиц.
Кэш / очередьRedisСессии, ограничение частоты запросов, ключи идемпотентности и очередь фоновых заданий.
Push-уведомленияFCM и APNs за единым сервисом уведомленийЕдиный внутренний API для уведомлений; различия между платформами обрабатываются на сервере, а не в приложении.
АдминистрированиеПанель администрирования на VueУправление пользователями, контентом и заказами, а также значениями удалённой конфигурации, которые меняют поведение приложения без выпуска новой версии.

Модель данных

Приведённые ниже таблицы содержат правила, от которых зависит всё остальное. Ошибки в них превращают работающий демонстрационный прототип в систему, которую невозможно расширять.

Основные сущности

СущностьКлючевые поля, связи и правила
user / auth_identityОдин пользователь может иметь несколько идентификаторов (телефон, Apple, Google, WeChat). Разделение идентификатора и пользователя позволяет добавлять способ входа позднее без миграции.
devicePush-токен, платформа, версия приложения и локаль для каждого устройства. Отсюда берутся данные для адресной доставки уведомлений и поэтапного выпуска.
order / bookingДоменная сущность с явным столбцом состояния и журналом переходов, поэтому служба поддержки может ответить на вопрос «как объект достиг этого состояния».
outbox (на стороне клиента)Поставленные в очередь локальные записи с UUID, созданным клиентом. Этот UUID становится ключом идемпотентности на сервере, благодаря чему повторная попытка после тайм-аута безопасна.
sync_cursorМетка времени updated_at для каждого пользователя, управляющая инкрементальной синхронизацией: приложение загружает изменения, а не запрашивает заново целые коллекции.
remote_configКонфигурация «ключ-значение» с привязкой к версии приложения и платформе, позволяющая менять правила и флаги функций без отправки приложения на проверку в магазин.

Ключевые интерфейсы

Конечные точки, содержащие бизнес-правила

Конечная точкаНазначение и примечания по конкурентному доступу
POST /api/v1/auth/tokenВыдаёт краткоживущий токен доступа и токен обновления с ротацией. Ротация токена обновления ограничивает ущерб от украденного токена на устройстве, к которому нет доступа.
GET /api/v1/sync?since=Инкрементальная загрузка записей, изменённых после указанного курсора, с постраничной выдачей и ограничением размера, чтобы пользователь, вернувшийся после нескольких недель автономной работы, не мог получить неограниченный ответ.
POST /api/v1/ordersПринимает UUID клиента в качестве ключа идемпотентности; повторный запрос после тайм-аута сети возвращает исходный заказ, а не создаёт дубликат.
POST /api/v1/devicesРегистрирует или обновляет push-токен, связанный с пользователем и версией приложения для адресных и поэтапных уведомлений.
GET /api/v1/configВозвращает удалённую конфигурацию для запрашивающей версии приложения — механизм, позволяющий не выпускать новую сборку для изменения правила.

Технические решения

  • Flutter вместо двух нативных кодовых баз. Рабочие процессы общие, а команда небольшая, поэтому общий код приложения может сократить дублирование обслуживания там, где рабочие процессы совпадают; платформенные интеграции, проверки устройств и выпуски всё равно требуют отдельных работ. Там, где платформы действительно различаются — платежи, push-уведомления, биометрия, — различие изолируется за платформенным каналом и не проникает в общий код.
  • Устойчивость к автономной работе, но не автономная работа как основа архитектуры. Чтение выполняется из кэша, а записи помещаются в клиентскую очередь outbox, но авторитетным источником остаётся сервер. Полноценная автономная работа с разрешением конфликтов обходится значительно дороже и оправдана только тогда, когда пользователи действительно работают без подключения в течение длительных периодов.
  • UUID, созданные клиентом, как ключи идемпотентности. В мобильных сетях регулярны тайм-ауты в середине запроса. Без этого повторные попытки после тайм-аута могут привести к риску создания дубликатов заказов, который необходимо тестировать.
  • Версионирование API с первого выпуска. Пользователи откладывают обновления, поэтому сервер должен продолжать обслуживать старые сборки. Добавление версионирования после запуска обходится значительно дороже, чем его внедрение с самого начала.
  • Удалённая конфигурация для бизнес-правил. Выпуски клиента зависят от проверки платформами и принятия обновления пользователями. Поддерживаемые пороги, тексты и флаги функций могут управляться на стороне сервера там, где это допускают правила платформ; изменения, требующие новой сборки приложения, сохраняют эту зависимость.

Гипотетические целевые показатели

Приведённые ниже значения являются гипотетическими примерами для планирования ёмкости, а не измеренными результатами клиента, проверенной рекомендацией по оценке ёмкости или соглашением об уровне обслуживания. Установите целевые показатели приёмки для конкретного проекта после определения нагрузки, устройств, данных, оборудования и зависимостей от сторонних систем; проверьте их с помощью пилотного запуска и нагрузочных тестов до фиксации производственной цели.

Цели по ёмкости и производительности

ЦельЗначение и допущение
Холодный запуск до первого содержательного экранаМенее 2 секунд на Android-устройстве среднего уровня при условии, что кэшированные данные отображаются, пока в фоне выполняется обновление по сети.
Инкрементальная синхронизацияРазмер пакета изменений менее 200 KB для типичного вернувшегося пользователя; размер страницы ограничен, поэтому система должна работать с ухудшением характеристик для пользователя, отсутствовавшего долгое время, а не завершаться по тайм-ауту.
Задержка APIp95 менее 300 мс для стандартных операций чтения, без учёта сторонних вызовов, задержку которых мы не контролируем.
Доставка push-уведомленийОпределите и измеряйте время постановки уведомления в очередь приложением и подтверждения со стороны провайдера. Итоговое время доставки зависит от платформы и не гарантируется этим примером.

Что входит в поставку

  • Исходный код приложения Flutter, исходный код бэкенда Go и исходный код администраторской панели Vue в вашем репозитории
  • Конфигурация сборки и подписи для обеих платформ, а также подготовка карточек в магазинах
  • Документация API, схема базы данных и история миграций
  • Инструкции по развёртыванию, мониторинг и доступ к журналам, процедура резервного копирования и восстановления
  • Поддержка отправки в App Store и Google Play; результат и сроки проверки остаются в зоне ответственности Apple и Google

Планирование для вашего бизнеса

Описанные выше модули — отправная точка, а не фиксированный пакет. Обычно мы ограничиваем первый выпуск одним основным рабочим процессом и одним административным рабочим процессом, а затем расширяем решение, когда реальные данные использования показывают, где фактически находятся нагрузка и нестандартные случаи. Отправьте техническое задание с определённым объёмом, и мы сопоставим его с этой архитектурой и сообщим, какие её части пока не нужны.

Изображения приложения

Flutter MVP для сервисного стартапа одного основателя

Запрос оценки проекта

Опишите цель продукта, текущий процесс, целевые платформы, ограничения и сроки решения. Мы оценим объём и предложим практичный следующий шаг.

Добавить требования к проекту (необязательно — для оценки объёма и стоимости)
Мы используем эти данные только для рассмотрения и ответа на ваш запрос по проекту. Ознакомьтесь с политикой конфиденциальности. Пожалуйста, не отправляйте пароли и секретные ключи API.

Demo Solutions