Modularizare aplicatie

Rasfoind internetul, citeam diverse chestii despre arhitecturi. Si am ajuns la microservicii vs monolit modular. Cand afli lucruri noi, te roade sa le si pui in practica :)) asa ca, dezvoltand o aplicatie care devine din ce in ce mai stufoasa si avand la baza 4 module/functii mari zic ca e ok sa incerc sa aplic noile cunostinte in acest proiect.

Frontendul e un SPA, care oricum era facut pe module, deci nu a fost ceva complicat sa trag niste foldere in altele si sa mut cateva fisiere. Totul logic pan’ aici.

Dar am ajuns in backend unde ma gandisem initial la 1 modul Core ce ar putea fi implementat in orice aplicatie. Asta ar contine Users, Roles si Logs. Apoi celelalte. Un exemplu mai bun o sa incerc mai jos:

Core:

  • controllers (UsersController, RolesController, LogsController, SettingsController)
  • models (User, Role, UserRole, UserSetting, Event, etc)
  • services (astea ar bate cu nr de controllere)
  • data (repositoryuri, entitati, conexiuneDb)

Orders:

  • controllers (OrdersController, SettingsController, +3)
  • models (Order, Product, UserOrder, + 20)
  • services (cate unul pentru fiecare controller)
  • data (repositoryuri, entitati, …)

Care este problema?

    1. pentru modulul Orders trebuie sa creez o alta conexiune la DB, sa folosesc conexiunea din CORE, sau sa duc conexiunea din core in afara lui si sa o folosesc in toate modulele.
    1. nu imi dau seama unde ar trebui sa incadrez UserOrder. Pentru ca sunt 2 variante: in UsersController pot sa am un getOrders, sau in OrdersController, unde deja am un getAll(), getById(), as putea avea si un getByUserId()

De ce m-am gandit la modularizare? Pentru ca momentan am dezvoltat doar un modul al aplicatiei (nu in totalitate) si deja am strans peste 20 modele, 8 controllere/servicii/repouri, nu folosesc nici un framework pentru db, deci scriu cod sql si asta ocupa enorm de mult spatiu in cod, am foarte multe metode si ma gandeam ca daca la un singur modul s-au strans atatea, daca le-as tripla (3 module), ar fi mult mai greu de lucrat, urmarit cod, modificat.

Sunt curios voi cum ati trata componentele comune in cazul asta, cele care se gasesc in minim 2 module? merci

:crazy_face:

Componentele comune le poti “duplica” fara nicio problema in fiecare context, la fel si datele. Oricum “order” din contextul orders si “order” din contextul user orders sunt diferite, alte date, alta functionalitate.

1 Like

Scapa de conceptul de Core, Common, Shared sau orice alta chestie similara care crezi tu ca te-ar ajuta sa nu duplici cod. Inevitabil vei ajunge sa duplici cod in context microservicii. Si asta e OK.

Mergand pe aceeasi idee ca @foobaz256, O alta impartire ar fi separarea aplicatiei pe domenii de business. Complet separate ca si codebase. Adica: Orders, Users and Roles, Settings, Catalog, Cart, etc.

De ce e ok sa “duplici cod”? Pai un caz concret ar fi un model/entitate de Product in context de Orders poate avea nevoie de niste proprietati/metode, iar in context de Catalog poate avea alte proprietati/metode. Unele pot fi comune, gen product_id, care ar fi ok sa fie uuid, dar asta e alta poveste.

Mai concret, un Product in context de Catalog poate avea nevoie de proprietatea “availability” sa zicem. Ca sa listezi in site daca e in stoc. In context de Cart la fel ai nevoie de availability pentru ca nu vrei sa accepti o comanda pentru un produs care nu e in stoc.

In context de Orders insa nu iti mai trebuie “availability” pentru ca teoretic alt microserviciu/context a avut grija de asta. Acolo iti trebuie, probabil, nume produs, sku, cantitate comandata. Nici poza teoretic nu iti trebuie acolo.
Ma rog, poate ma insel sau poate nu, e discutabil, am vrut doar sa arat faptul ca sunt, sau ar trebui sa fie, entitati sau modele diferite in aplicatia ta. Fiecare cu use-case-urile lor.

2 Likes

Iti recomand cartile astea 2:


https://www.amazon.com/Domain-Driven-Design-Distilled-Vaughn-Vernon-ebook/dp/B01JJSGE5S/

Sunt destul de greu de digerat, mai ales aia rosie, dar e posibil sa iti raspunda la multe intrebari.

1 Like

Serios? mie mi s-a parut aia rosie mai usor de digerat :laughing:

600 de pagini, te si plictisesti, oricum e parfum pe langa cum scrie Eric Evans

Well, nu sunt cel mai mare expert in microservicii dar as avea cateva observatii.

Microserviciile nu sunt despre modularitate (pe care o atingi usor si in aplicatii monolit) ci despre scalabilitate. In primul rand trebuie sa faci o evaluare buna daca acest lucru merita (mai ales pe o aplicatie existenta) intrucat trebuie sa schimbi complet arhitectura pentru ca daca spargi aplicatia in patru si o pui in patru locuri aia nu inseamna microservicii.

Microserviciile inseamna sa atomizezi operatiile ca sa nu ai cod redundant si apoi sa schimbi date intre ele. Adica nu faci un microserviciu care face jdemii de operatii ci mai multe care apeleaza alte microservicii and so on…

Evident treaba se complica de aia trebuie sa sti exact daca merita efortul si unde vrei sa ajungi cu aplicatia. De asemenea daca intri in zona trebuie sa te ai bine cu partea de containere ( eg. Docker) si Kubernetes.

Ca si recomandare daca nu ai o restrictie de limbaj iti recomand Go la microservicii, iti va usura foarte mult viata fata de alte tehnologii (inclusiv pe partea de deploy).

2 Likes

Stati, stati, nu ma refeream la microservicii modulare (nici nu stiu daca exista). Microserviciile ies din discutie in cazul aplicatiei despre care vorbesc. Ah, vina mea, acum vad ca n-am specificat ca as fi vrut sa aplic modularizarea pe proiect (monolit) si am intrat direct in detalii.
Scenariu: am un folder cu 30 controllere, altul cu 100 modele. In cazul asta m-am gandit ca ar fi perfect sa structurez aplicatia pe module, fiecare cu controllerele si modelele sale. La baza ar fi un singur build, modificarea ar fi doar din punct de vedere al structurii folderelor.

Problema mea era duplicarea, cum au spus @foobaz256 si @tacheshun Order intr-un context inseamna ceva, in altul altceva. E sacaitoare ideea de duplicare a codului, cand in minte am tocmai sa scriu cat mai mult cod reutilizabil. Doar ca, in unele cazuri nu se poate :crazy_face: ori daca se poate, incalci alte principii, si tot asa.

Pentru carti trebuie sa-mi fac curaj, mi-am mai luat 2 si imi pierd interesul repede, e mult mai frumos ceva practic curs/tutorial :rage: (trebuie sa-mi scot din minte chestia asta:))

1 Like