A modern webalkalmazások fejlesztése során elengedhetetlen a különböző modulok és azok hatékony betöltése, különösen akkor, amikor több felhasználói szerepkör és funkcionalitás is jelen van. Egy jól megtervezett alkalmazás struktúra nem csupán a felhasználói élményt javítja, hanem jelentősen csökkentheti az alkalmazás méretét és gyorsabbá teheti a betöltési időt. Az Angular keretrendszerben a modulok szervezése és a lazy loading alkalmazása alapvető fontosságú lehet a nagyobb, összetettebb alkalmazásokban, ahol a különböző felhasználói szerepköröknek más-más modulokhoz kell hozzáférniük.

A kezdő fejlesztők számára az egyik legfontosabb elv, hogy minden felhasználói szerepkörhöz egyedi hozzáférési jogokat rendeljenek. Ezen a ponton a három legfontosabb modul, amelyet érdemes külön-külön kezelni, a következő:

  • Point of Sale (POS): A pénztárosok csak a POS modult és annak komponenseit használják.

  • Inventory: Az árufeltöltők a készletkezelő modulhoz férnek hozzá, amely további képernyőket tartalmaz a termékek, kategóriák és készletbevitel kezelésére.

  • Manager: A menedzserek mindhárom modulhoz hozzáférhetnek, beleértve a felhasználói kezelés és a nyugták lekérdezésének funkcióit.

A lazy loading alkalmazásával ezek a modulok hatékonyan elkülöníthetők egymástól, lehetővé téve, hogy a felhasználók kizárólag azokhoz a komponensekhez férjenek hozzá, amelyekre szükségük van. A pénztárosok például soha nem fogják használni a készletkezelő modul elemeit, így nincs értelme ezeket a komponenseket letölteni az ő eszközeikre. Ezáltal az alkalmazás mérete és memóriahasználata is csökkenthető, miközben a teljesítmény jelentősen javul. Ha később a Manager modulhoz újabb funkciók, például fejlettebb riportok vagy új szerepkörök kerülnek, a POS modul teljesítménye nem fog csökkenni a növekvő alkalmazás miatt. Ennek következményeként kevesebb támogatói hívásra lesz szükség, és a hardver erőforrásai hosszabb ideig lesznek elegendőek.

A modulok elkészítésekor az első lépés a megfelelő modulok és azok routing konfigurálása. Ehhez a következő parancsokat kell futtatnunk, hogy létrehozzuk a különböző funkciókhoz szükséges modulokat:

sql
$ npx ng g m manager --routing $ npx ng g m inventory --routing $ npx ng g m pos --routing $ npx ng g m user --routing

Miután a modulokat létrehoztuk, ellenőrizzük, hogy a CLI parancsok sikeresen lefutottak-e, és a megfelelő fájlok valóban létrejöttek a projekt struktúrájában. Ekkor már elkezdhetjük a modulok belső konfigurációját, például a ManagerModule-ot, amely a következő kódrészlet szerint lesz konfigurálva:

typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ManagerRoutingModule } from './manager-routing.module'; @NgModule({ imports: [CommonModule, ManagerRoutingModule], declarations: [], }) export class ManagerModule {}

Itt az @NgModule dekorátorral jelezzük, hogy ez egy Angular modul, amely tartalmazza a szükséges importokat és routing konfigurációkat.

A routing kialakításánál fontos, hogy a modulok közötti kapcsolatokat helyesen állítsuk be, különösen a különböző modulszintű route-okat. Ha például a ManagerRoutingModule-ban definiálunk egy útvonalat, akkor azt a router automatikusan az /manager útvonal elé fogja illeszteni, mivel ezt előzőleg specifikáltuk. Ez az elkülönítés biztosítja, hogy minden modul külön-külön is működőképes legyen, és más modultól függetlenül tölthető be.

Az alkalmazásunk alapértelmezett kezdőlapjának megtervezésekor fontos figyelembe venni, hogy a fő oldal ne tartalmazzon túl sok komplex layoutot. Az AppComponent a főkomponens, amelynek csak az állandó elemeket, mint például az eszköztárat kell tartalmaznia. Ezzel szemben a landing page (kezdőoldal) komponensét érdemes külön modulban kezelni, így a kód jobban strukturált lesz, és minimalizáljuk az alkalmazás első betöltődési idejét.

A route-ok konfigurálása során alapértelmezett beállítást kell alkalmaznunk, hogy az alkalmazás mindig a /home route-ra irányítsa a felhasználókat. Ha a felhasználó olyan útvonalat próbál elérni, amely nem létezik, akkor a rendszer automatikusan a PageNotFoundComponent-re irányítja, biztosítva ezzel a felhasználóbarát navigációt.

Ezeknek a konfigurációknak a megértése és alkalmazása nem csupán a fejlesztői hatékonyságot növeli, hanem jelentősen javítja az alkalmazás karbantarthatóságát és jövőbeli bővíthetőségét. A modulok és a route-ok struktúrája szoros összefüggésben állnak egymással, és az optimális működés érdekében a fejlesztőknek mindig figyelemmel kell kísérniük, hogy hogyan hatnak egymásra a különböző komponensek.

Hogyan valósítható meg biztonságos hitelesítés és jogosultságkezelés modern Angular alkalmazásokban?

Az Angular keretrendszerben a biztonságos és rugalmas hitelesítés megvalósítása kulcsfontosságú a megbízható felhasználói élmény és az adatvédelem szempontjából. A hitelesítés alapját képező komponensek integrálása során érdemes újrahasználható UI szolgáltatásokat létrehozni, amelyek lehetővé teszik például riasztások kényelmes megjelenítését az alkalmazás vezérlési logikájában. Az útvonalvédők (route guards) alkalmazása megakadályozza, hogy az illetéktelen felhasználók olyan képernyőkre lépjenek be, amelyekhez nincs jogosultságuk, ezáltal növelve az alkalmazás biztonságát és integritását. Fontos hangsúlyozni azonban, hogy a valódi biztonságot a szerveroldali megvalósítások biztosítják, így a kliensoldali védelem inkább a felhasználói élményt szolgálja.

A dinamikus hitelesítő szolgáltatók használata, például gyártmány (factory) minta segítségével, lehetővé teszi, hogy különböző környezetekben eltérő autentikációs megoldásokat alkalmazzunk, így például fejlesztési, tesztelési vagy éles környezetben más-más hitelesítési szolgáltatót lehessen használni. Ez a rugalmasság megkönnyíti a skálázhatóságot és a karbantarthatóságot.

Egy valós példán keresztül a Firebase hitelesítés implementálása mutatja be, hogyan lehet egy komplett és megbízható autentikációs rendszert integrálni Angular alkalmazásba. A Firebase Auth egy jól dokumentált és széles körben használt szolgáltatás, amely egyszerűsíti a felhasználók kezelését, ugyanakkor meg kell érteni a vele járó kompromisszumokat, mint például a függőség egy harmadik féltől vagy a költségek alakulása.

Az alkalmazások egyre komplexebbé válásával a REST és GraphQL API-k használata elengedhetetlen, különösen a teljes körű full-stack fejlesztés során. A MEAN stack, amely a MongoDB, Express.js, Angular és Node.js technológiákból áll, kiváló alapot nyújt az egységes fejlesztői élményhez és hatékony teljesítményhez. A szerveroldalon a JWT (JSON Web Token) alapú hitelesítés biztosítja az API végpontok védelmét, lehetővé téve a token-alapú, állapotmentes autentikációt, amely skálázható és biztonságos.

A LemonMart szerver példáján keresztül látható, hogyan lehet egy monorepós architektúrát alkalmazni, amely Docker Compose segítségével futtat háromrétegű alkalmazást (webalkalmazás, szerver, adatbázis). Ez a megközelítés segíti a fejlesztést és a telepítést, miközben egyértelművé teszi az egyes komponensek közötti kapcsolatokat.

Az API-k kialakításánál fontos a jól dokumentált és szabványosított megközelítés, amelyhez REST esetén az OpenAPI specifikáció és SwaggerUI, GraphQL esetén pedig az Apollo Studio használata járul hozzá. Az Express.js és TypeScript együttes alkalmazása biztosítja az átlátható, karbantartható és típusbiztos kódot, amely könnyen bővíthető.

Az adatmodell kezelésében a MongoDB Object Document Mapper (ODM), például a DocumentTS könyvtár, támogatja az adatbázis hatékony és típusbiztos kezelését, lehetővé téve a felhasználói adatok és hitelesítő adatok megbízható tárolását. Ez az integráció szerves része a biztonságos autentikációs folyamatnak.

Az RBAC (Role-Based Access Control) megvalósítása mind a REST, mind a GraphQL API-k esetében lehetővé teszi a szerepalapú hozzáférés-szabályozást, amely finomhangolja a jogosultságokat és biztosítja, hogy a felhasználók csak az engedélyezett műveleteket végezhessék el. Ez a modell kiterjeszthető és moduláris, így könnyen integrálható az alkalmazás különböző részeibe.

A fejlesztői környezet megfelelő beállítása, mint például a Docker Desktop és Postman használata, elengedhetetlen a hatékony teszteléshez és futtatáshoz. A GitHub-ról elérhető példakód klónozása és az environment változók konfigurálása biztosítja a projekt gördülékeny indítását.

Mindezek mellett az olvasónak érdemes tisztában lennie azzal, hogy a kliensoldali biztonsági megoldások, mint az Angular route guard-ok, inkább a felhasználói élményt javítják, de az igazi védelem a szerveroldalon történik. Emellett a jól megtervezett API-k kulcsfontosságúak az alkalmazás teljesítményének és megbízhatóságának biztosításához, ezért az API tervezésbe és dokumentálásba fektetett idő és energia közvetlenül megtérül. A fejlesztés során a moduláris, újrahasználható komponensek alkalmazása, a tesztelhetőség és a skálázhatóság végig szem előtt tartandó szempontok. Az autentikáció és jogosultságkezelés nem csak biztonsági kérdés, hanem a felhasználói élmény és az alkalmazás működőképességének alappillére is.

Hogyan konfiguráljunk egy teljes veremű monorepót Nx és NestJS segítségével?

Az Nx fontos követelmény. A legtöbb Angular monorepo csak frontend kódot tartalmaz. Ha szeretnénk egy teljes veremű monorepot konfigurálni egy meglévő Angular munkaterületen NestJS segítségével, először telepítenünk kell a Nest schemat, majd új projektet generálhatunk az Nx munkaterületen belül:

bash
$ npm i -D @nrwl/nest $ npx nx g @nrwl/nest:application apps/your-api

A telepítés után részletesebben is olvashatsz erről a konfigurálásról a https://www.thisdot.co/blog/nx-workspace-with-angular-and-nest/ linken.

Ezután nézzük meg, hogyan van konfigurálva a LemonMart szerver monorepo-ja. A Git almodulok segítenek kódot megosztani több tároló között, miközben megőrzik a commitok elkülönítését. A frontend fejlesztők választhatják, hogy csak a frontend tárolóval dolgoznak, míg a teljes veremű fejlesztők inkább hozzáférnek az összes kódhoz. A Git almodulok egy kényelmes módot kínálnak a meglévő projektek egyesítésére.

Vegyük szemügyre a lemon-mart-server projekt teljes struktúráját, ahol három fő mappát találunk:

pgsql
lemon-mart-server
├───bin ├───web-app (lemon-mart snapshotja) ├───server │ package.json │ README.md

A bin mappa segédprogramokat vagy eszközöket tartalmaz, a web-app mappa a frontendet jelenti, míg a server mappa tartalmazza a backend forráskódját. Ebben az esetben a web-app mappa a lemon-mart projektet tartalmazza. A kódot nem kell másolnunk a meglévő projektből, helyette a Git almodulokat használjuk két tároló összekapcsolására.

A package.json fájlban találhatóak azok a parancsok, amelyek segítenek a Git almodulok inicializálásában, frissítésében és tisztításában, mint például a modules:update, amely a legfrissebb verzióját szerzi meg a web alkalmazásnak.

Ha a lemon-mart-server-t GitHubról klónoztuk, végezzük el az alábbi lépéseket a web-app mappa inicializálásához:

  1. Frissítsük a webAppGitUrl változót a saját projektünk URL-jére.

  2. Hajtsuk végre a webapp:clean parancsot a meglévő web-app mappa eltávolításához.

  3. Végül hajtsuk végre a webapp:init parancsot, hogy inicializáljuk a projektünket a web-app mappában.

Ezt követően a modules:update parancs segítségével frissíthetjük az almodul kódját. Ha új környezetben klónozzuk a repót, az npm modules:init parancsot kell futtatnunk az almodulok letöltéséhez.

A kódunk most már elérhető a web-app mappában, és az alábbi módon kellene látnunk mindkét projektet a VS Code forrásvezérlőjében. A VS Code forrásvezérlő segítségével függetlenül végezhetünk Git műveleteket mindkét tárolón.

Ha valami probléma adódna az almodulokkal, egyszerűen navigáljunk az almodul mappájába, futtassuk a git pull és git checkout main parancsokat, hogy visszaállítsuk az alapértelmezett ágat.

A következő lépés a CircleCI konfigurálása. A Git almodulok egyik előnye, hogy a frontend és a backend ugyanabban a CI pipeline-ban történő tesztelése egyszerűen megvalósítható. A config.yml fájl két munkát valósít meg a következő munkafolyamatban:

yaml
.workflows:
build-and-test-compose: jobs: - build_server - build_webapp

A pipeline lekéri a kódot, ellenőrzi a használt csomagok biztonságát az audit-ci-val, telepíti a függőségeket, ellenőrzi a stílus- és linting hibákat, futtatja a teszteket, és ellenőrzi a kód lefedettségét. A tesztelési parancsok automatikusan felépítik a backend kódot, amely a dist mappában található. A végső lépésben a dist mappát áthelyezhetjük a munkaterületre, hogy későbbi szakaszokban használhassuk.

Ez a CI pipeline párhuzamosan építi fel a szervert és a webalkalmazást, és lehetőséget ad a deploy feladat futtatására, ha a munkák sikeresen lefutottak az main ágon.

A REST és GraphQL API-k tervezése során fontos, hogy az API-kat adatbázis entitások köré tervezzük. A frontend és backend csapatok közötti korai együttműködés a tervezésben kulcsfontosságú, mivel lehetővé teszi, hogy a két csapat egy szerződést készítsen, amely alapján mindkét csapat felépítheti saját részét a szoftvernek. A legfontosabb célok a következőek:

  • Minimalizáljuk az adatátvitelt a kliens és a szerver között.

  • Kövessünk jól ismert tervezési mintákat (például oldalszámozási API-tervezést).

  • Csökkentsük az üzleti logika megvalósítását a kliensen.

  • Adatstruktúrákat síkítsunk ki, amikor határokat lépünk át.

  • Ne exponáljuk az adatbázis kulcsokat vagy idegen kulcs kapcsolataikat.

  • Az API végpontokat már a kezdetekben verzionáljuk.

Ezen kívül az API felület mögötti összes üzleti logikát a backend-en kell megvalósítani, míg a frontend csak a prezentációs logikát tartalmazza. Mindezt a háttérben lévő stateless dizájnra alapozva kell megvalósítani, hogy lehetővé váljon a könnyed skálázás a felhőplatformokon.

Az API-k tervezésében minden lépés figyelembevételével csökkenthetjük a hibák lehetőségét, és biztosíthatjuk, hogy az alkalmazásunk később könnyen skálázható és karbantartható legyen.