Anatomia unei aplicații care crește sănătos
Lectură estimată: 4 minute
Estimare pentru text, la un ritm de 180 de cuvinte pe minut. Timpul pentru analizarea codului, exerciții și proiecte se adaugă separat și depinde de ritmul tău.
Problema pe care o vei rezolva: Comandă și notificare după tranzacție
Comanda fictivă are două poziții: 2 × 1.500 bani și 1 × 2.000 bani. Notificarea trebuie planificată doar dacă salvarea comenzii reușește. Simulează o excepție la a doua poziție.
Rezultatul urmărit
Separă validarea, autorizarea și serviciul de creare. Testează succesul și rollbackul. Documentează momentul în care jobul devine eligibil pentru rulare.
Cum recunoști o soluție corectă
Totalul este 5.000 bani. La excepție nu rămâne o comandă parțială și nu se trimite notificarea de succes. Testul verifică și baza, și coada de joburi.
Parcurge lecțiile în ordine și păstrează exercițiile în registrul descărcabil. Ultima lecție include atelierul de 40 de minute în care combini conceptele și testezi o variație a situației inițiale. Exemplele comerciale sunt fictive; nu reprezintă rezultate ale unor clienți.
O aplicație mică se ține în controllere. Una care crește are nevoie de structură: logica de business separată de HTTP, validare dedicată, autorizare centralizată, sarcini lente puse pe cozi, efecte secundare prin evenimente. Lecția asta e harta acestor straturi și când introduci fiecare.
Simptomele unei aplicații care „scârțâie"
- Controllere de 300 de linii cu logică de business, validare și răspuns amestecate.
- Aceeași regulă (ex: „doar autorul editează") copiată în 5 locuri.
- Cereri HTTP lente pentru că trimit email sau procesează imagini în timpul cererii.
- Frică să modifici ceva pentru că nu știi ce se rupe.
Straturile
- Controller: primește cererea, cheamă un serviciu, întoarce un răspuns. Subțire.
- Form Request: validarea și autorizarea de intrare.
- Service / Action: logica de business, testabilă independent de HTTP.
- Model: date și relații, plus scope-uri și accesori.
- Job: munca lentă, rulată asincron.
- Event / Listener: efecte secundare decuplate (notificări, logare, cache).
Când introduci fiecare strat
Nu peste tot, din prima. Un CRUD simplu stă bine într-un controller. Extragi un serviciu când logica are mai mulți pași, se repetă, sau vrei s-o testezi. Adaugi un job când o operație durează peste ~200ms. Adaugi un event când vrei să reacționezi la ceva fără să cuplezi codul care declanșează de codul care reacționează.
Exercițiu
Ia un controller din proiectul tău (sau unul exemplu) cu peste 100 de linii. Identifică ce e validare, ce e logică de business, ce e formatare de răspuns. Schițează cum l-ai împărți pe straturi.
Greșeli frecvente
- Aplici toate straturile de la început, pe un CRUD banal — over-engineering.
- Nu aplici niciun strat și ajungi cu „God controllers".
- Muți cod în „servicii" care sunt doar controllere redenumite.
- Confunzi „mai multe fișiere" cu „arhitectură mai bună".
De reținut
- Controllere subțiri: cerere → serviciu → răspuns.
- Straturi: Form Request, Service/Action, Model, Job, Event/Listener.
- Introduci un strat când apare durerea, nu preventiv.
- Serviciile există ca să izolezi și să testezi logica de business.
Pe scurt
O aplicație sănătoasă are straturi cu responsabilități clare, introduse pe măsură ce complexitatea o cere.
Granițe între HTTP, regulă de business și persistență
O aplicație crește mai ușor când regula principală nu depinde direct de cererea HTTP. Controllerul validează și autorizează, serviciul execută operația, iar modelul reprezintă datele. Nu este necesar un strat pentru fiecare linie de cod; separarea are sens când o regulă este reutilizată sau are efecte coordonate. Pentru aprobarea unei solicitări, definește starea inițială permisă și rezultatul, nu doar numele metodei.
Exemplu de lucru
Flux: Request validat → policy → ApproveServiceRequest → tranzacție → răspuns.
Regulă: numai cererile new pot deveni approved.
Invariante: proprietarul nu se schimbă; o aprobare repetată nu creează două notificări.
Teste: stare validă, stare invalidă, acces refuzat, repetare.Interpretarea rezultatului
Un controller scurt nu este automat o arhitectură bună dacă serviciul acceptă orice stare. Urmărește regula și efectele secundare. Pentru operații concurente, simpla verificare a statusului înaintea salvării poate necesita protecție suplimentară prin tranzacție sau actualizare condiționată.
Exercițiu de consolidare
Descrie unde ai pune validarea formatului emailului și unde regula „o cerere anulată nu poate fi aprobată”.
Aplicație practică
Sarcina
Cartografiază fluxul de creare a unei comenzi demonstrative.
Rezolvare orientativă și verificare
Controllerul coordonează, request-ul validează, serviciul aplică regulile, jobul trimite notificarea după commit.
Greșeală de evitat
Nu adăuga abstracții fără o responsabilitate reală.
Documentație și surse
- Documentația Laravel 11 — versiunea aplicației demonstrative — Laravel
- OWASP Top 10 — OWASP
Materiale pentru această lecție
Ți-a plăcut lecția? Continuă cursul complet
Ai citit o lecție gratuită. Celelalte lecții, aplicațiile practice și materialele se deblochează odată cu cursul.
249 lei
Plată unică, acces pe viață la toate cele 7 lecții.
Vezi ce conține cursul →