D
D
donflash2019-08-28 13:55:58
symfony
donflash, 2019-08-28 13:55:58

How to avoid code duplication for a horizontally scalable web application?

We are developing an application (symfony4) that has a control panel (admin panel) on one side, and a http restful api backend on the other. The database is shared, it is planned to make master(writes)->slave(reads) replicas with the slaves balancer (haproxy). The admin will only be vertically scalable, while the backend api will be horizontal.
Suppose in the admin panel you need to manage clients and banks (CRUD), this data flies to the master. Next comes the interaction with the backend api, which should pick up clients and banks from the slave and give it in the form of json.
In my opinion, it is correct to divide the designed application into two - admin panel and backend api. They have different dependencies and configs, as well as containerization requirements, which further adds to the confidence that doing two independent applications is correct.
But in this case, the duplication of the client and bank entities confuses me. It turns out that if you need to add a field to one entity, then it will have to be changed in two applications at once. Creating a common bundle with entities also seems to be the wrong decision. I thought about making communication between these applications at the level of HTTP requests, but then all the backend api will be hammered into the admin panel, which is not consistent with the scaling requirements.
What is the correct architectural approach?

Answer the question

In order to leave comments, you need to log in

5 answer(s)
V
vism, 2019-08-29
@vism

As I see it, I did exactly that - move the common code to a separate repository and connect it where necessary.
If you need to process this data somehow, decorate it already in a specific application.
If these applications are similar to you now, then it is not known what will happen in a few years. And moving it to a separate repository will give flexibility to the architecture.
If the logic layer is moved to a separate repository, it is very desirable to have a layer in the final application in order to properly prepare the data. So that changes in the repository with logic do not break another application.
Pounding over HTTP looks delicious, but there are all the shortcomings of the repository and a bunch of others.
Update:
Philipp , xmoonlightand I write about the same in different words, as far as I understand. At least Philipp 's answer is what I mean.

P
Philipp, 2019-08-29
@zoonman

Let me rephrase xmoonlight a bit. There is a separation of the data model and its various representations.
Create a common repository with models and serialize through inheritance with the return of the necessary structures for the admin panel and API.
For APIs, implement the view in whitelist style. As the system expands, compatibility will be maintained.
Implement work with data through a common service layer in which business logic will live.
In this case, business processes will be implemented regardless of interfaces, which means fewer bugs, etc.

I
Igor, 2019-09-01
@IgorPI

My five cents.
Specifically, from the current situation in a real project, at the moment, its significance is not particularly high, but I already get money for it.
That is to say, an investment in development.
I have been designing my own framework for a year, there are some achievements.
Immediately make a reservation, I also use third-party code.
In particular, I use Doctrine ORM and a number of other components from Symfony and others.
For example, your routing, your own loading of services ...
I spent a lot of effort, and the customer spent money.
The framework is already ready.
During development, I encountered a number of problems, just with code duplication.
Yes, this problem is partially solved.
For example:
Entities and entity repositories are common code for all environments.
There can be any number of environments.
At the moment I use two environments
Admin
Api
admin.mysite.com
api.mysite.com
mysite.com - for example, the front is generally on NUXT
The environments have a common config
Common language packs with lazy loading
This is how controllers look in their environments
In principle, there is no code that written only for a specific environment, with the exception of controllers and application loaders.
Entry points are always equal to the number of environments, but the application loader is one
Application startup file code

<?php

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

In the controller, each environment can have duplicate methods
. For myself, I singled out an informal definition of the
Function, I put the modules that solve the same task for all environments into a separate folder
. Visually, it looks like this
5d6aed5540883788430736.png

X
xmoonlight, 2019-08-28
@xmoonlight

1. Admin and backend API are object manipulators.
2. Repository of objects (their properties and relationships) - must be centralized: usually, these are relationships and entities in the database.
3. To manage the repository of objects, you can create another manipulator (with its own API) and access it, if necessary, from the "admin panel" and / or "backend API".
The main thing is to read the database manual in order to use all the possibilities for manipulating and storing the structure of objects you need.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question