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

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

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

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

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

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

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

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

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

Update:
Philipp , xmoonlight и я о том же пишем разными словами, насколько я понимаю. По крайней мере ответ Philipp это то, что я имею ввиду.
Ответ написан
zoonman
@zoonman
CEO @ LinuxQuestions.ru
Немного перефразирую 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
Вот возникла ситуация, когда надо использовать одинаковые вещи во многих местах, логично вынести их в отдельных пакет. Подключаешь туда, подключаешь сюда, и получаешь уверенность в том, что ты работаешь с одинаковыми наборами данных. Круто же? Останется только обновлять пакет.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
AGIMA Москва
от 180 000 руб.
DiState Санкт-Петербург
от 80 000 до 140 000 руб.
17 окт. 2019, в 03:16
37500 руб./за проект
16 окт. 2019, в 22:58
3200 руб./за проект
16 окт. 2019, в 22:43
3000 руб./за проект