Как избежать дублирования кода для горизонтально масштабируемого веб-приложения?

Разрабатываем приложение (symfony4), у которого с одной стороны есть пульт управления (админка), а с другой backend http restful api. БД общая, планируется сделать master(writes)->slaves(reads) реплики с балансировщиком slaves (haproxy). Админка будет только вертикально масштабируемой, а backend api горизонтально.

Предположим в админке нужно управлять клиентами и банками (CRUD), эти данные улетают в master. Далее идет взаимодействие с backend api, который должен забрать клиенты и банки из slave и отдать в виде json.

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

Но в таком случае меня смущает дублирование сущностей клиент и банк. Получается, если нужно добавить поле в одну сущность, то ее придется менять сразу в двух приложениях. Создавать общий бандл с сущностями тоже видится неверным решением. Думал сделать общение между этими приложениями на уровне HTTP запросов, но тогда в админку будет долбиться все backend api, что не согласовывается к требованиям масштабирования.

Подскажите правильный архитектурный подход?
  • Вопрос задан
  • 1453 просмотра
Пригласить эксперта
Ответы на вопрос 5
@vism
Как мне видется, и имено так и делал - вынести общий код в отдельный репозитарий и подключать где нужно.
Если нужно эти данные уже как-то обработать, декорируете их уже в кокретном приложении.

Если у вас сейчас эти приложения похожи, то не известно, что будет через несколько лет. А вынос в отдельный репозитарий даст гибкость для архитектуры.

Если выносится слой логики в отдельный репозитарий, очень желетельно иметь прослойку в конечном приложении, чтоб уже данные правильно готовить. Чтоб изменения в репозитарии с логикой, не поломали другое приложение.

Долбится по HTTP выглядит вкусно, но там все недостатки репозитария и еще куча других.

Update:
Philipp , xmoonlight и я о том же пишем разными словами, насколько я понимаю. По крайней мере ответ Philipp это то, что я имею ввиду.
Ответ написан
Комментировать
zoonman
@zoonman
⋆⋆⋆⋆⋆
Немного перефразирую xmoonlight. Налицо разделение модели данных и различных ее представлений.
Создайте общий репозитарий с моделями и через наследование сделайте сериализацию с возвращением нужных структур для админки и API.
Для API представление реализуйте в стиле белого списка. При расширении системы будет сохраняться совместимость.
Работу с данными реализуйте через общий сервисный слой, в котором будет жить бизнес-логика.
В таком случае бизнес-процессы будут реализованы вне зависимости от интерфейсов, а значит меньше багов и т.д.
Ответ написан
Комментировать
IgorPI
@IgorPI
Свои пять копеек.
Конкретно из текущей ситуации в реальном проекте, на данный момент, его значимость не особо высока, но уже за это получаю деньги.

Так сказать инвестиция в развитие.

На протяжении года занимаюсь проектированием собственного фреймворка, есть некие достижения.
Сразу оговорюсь, я тоже использую сторонний код.
В частности я использую Doctrine ORM и ряд других компонентов от Symfony и других.
Например роутинг свой, загрузка сервисов своя...

Очень много сил потратил, а заказчик средств.
Фреймворк уже готов.

При разработке столкнулся с рядом проблем, как раз с дублированием кода.
Да, эта проблема частично решена.

Например:

Сущности, и репозитории сущностей - это общий код для всех окружений.
Окружений может быть сколько угодно.

На данный момент использую два окружения
Admin
Api

admin.mysite.com
api.mysite.com
mysite.com - например фронт вообще на NUXT

У окружений есть общий конфиг
Общие языковые пакеты с ленивой загрузкой

Вот так выглядят контроллеры в своих окружениях
5d6ae80b31c6d516616002.png

В принципе нет кода который пишется только для конкретного окружения, исключением являются контроллеры и загрузчики приложения.

Точек входа всегда ровно количеству окружений, но загрузчик приложения один
5d6aeab1c0789688262811.png
Код файла запуска приложения
<?php

define('ENV', basename(__DIR__));
require '../../engine/bootstrap.php';


В контроллере у каждого окружения могут быть дублирующие методы

Для себя выделил неформальное определение

Функции, модули которые решают одну и туже задачу для всех окружений, выношу в отдельную папку
Визуально это выглядит так

5d6aed5540883788430736.png
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
1. Админка и бэкенд API - это манипуляторы объектов.
2. Репозиторий объектов (их свойств и взаимосвязей) - должен быть централизованный: обычно - это связи и сущности в БД.
3. Для управления репозиторием объектов можно создать ещё один манипулятор (со своим API) и обращаться к нему по необходимости из "админки" и/или "бэкенд API".

Главное - читайте мануал к БД, чтобы использовать все возможности для манипуляции и хранения нужной Вам структуры объектов.
Ответ написан
profesor08
@profesor08
Вот возникла ситуация, когда надо использовать одинаковые вещи во многих местах, логично вынести их в отдельных пакет. Подключаешь туда, подключаешь сюда, и получаешь уверенность в том, что ты работаешь с одинаковыми наборами данных. Круто же? Останется только обновлять пакет.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы