| .. | ||
| DomainServiceProvider.php | ||
| HandleDomainLogic.php | ||
| ProposedKernel.php | ||
| README.md | ||
Optimierung des Domain-Routings und Session-Handlings
Dieses Dokument beschreibt eine vorgeschlagene Optimierung für die bestehende Domain-Routing- und Session-Verwaltungslogik.
1. Analyse der aktuellen Architektur
Die Anwendung nutzt eine komplexe, aber leistungsstarke Multi-Domain-Architektur, um verschiedene Anwendungsbereiche (Hauptseite, CRM, Partner-Portal, Checkout, User-Shops) voneinander zu trennen.
- Konfiguration: Die Domain-Struktur wird zentral in
config/domains.phpdefiniert. - Service Provider (
DomainServiceProvider):- Registriert den
DomainService(zuständig für Domain-Analyse und UserShop-Logik). - Registriert den
DomainContextals Singleton, der pro Request Informationen über die aktuelle Domain enthält (Typ, Host, Subdomain, UserShop-Objekt). - Wichtig: Er registriert die
DomainResolver-Middleware und fügt sie an den Anfang derweb-Middleware-Gruppe hinzu.
- Registriert den
- Middleware (
DomainResolver):- Nutzt den
DomainContext, um die Anfrage zu validieren. - Leitet ungültige Domains auf die Hauptdomain um.
- Prüft den Status von User-Shops (aktiv, Zahlung etc.).
- Problembereich: Schreibt
UserShop-Daten aktiv in die Session (Session::put,Session::save).
- Nutzt den
- Routing (
RouteServiceProvider): Lädt die passenden Routen-Dateien basierend auf demtypeimDomainContext.
2. Identifiziertes Problem: Konflikte bei der Session-Erstellung
Das Kernproblem liegt in der Reihenfolge, in der die Middleware ausgeführt wird.
- Der
DomainServiceProviderregistriert dieDomainResolver-Middleware mitprependMiddlewareToGroup('web', ...). - Dadurch wird
DomainResolvervor der Standard-Laravel-MiddlewareStartSessionausgeführt, die ebenfalls Teil derweb-Gruppe ist. - Die
DomainResolver-Middleware versucht, auf die Session zuzugreifen und sie zu modifizieren (Session::put,Session::save). Da dieStartSession-Middleware noch nicht gelaufen ist, wird hier möglicherweise eine "provisorische" Session gestartet. - Anschließend läuft die
StartSession-Middleware, die die "offizielle" Session aus dem Cookie lädt. - Dies kann zu einem Konflikt führen, bei dem zwei verschiedene Session-Instanzen pro Anfrage existieren oder die in
DomainResolvergespeicherten Daten nicht in der finalen Session-Response an den Client gesendet werden. Das Resultat ist, dass derUserShop-Kontext beim Wechsel zwischen Domains (z.B. vom Shop zumin.-Portal) verloren geht.
3. Vorgeschlagene Lösung: Saubere Trennung und korrekte Reihenfolge
Die vorgeschlagene Lösung zielt darauf ab, die Logik zu entzerren und die Middleware in der korrekten, von Laravel vorgesehenen Reihenfolge auszuführen.
Schritt 1: Korrektur der Middleware-Reihenfolge
Die DomainResolver-Middleware darf nicht mehr per prependMiddlewareToGroup im Service Provider registriert werden. Stattdessen sollte sie im app/Http/Kernel.php innerhalb der web-Gruppe nach der \Illuminate\Session\Middleware\StartSession-Middleware platziert werden.
Dadurch wird sichergestellt, dass die Session immer korrekt initialisiert ist, bevor unsere anwendungsspezifische Logik darauf zugreift.
Schritt 2: Aufteilung der Middleware-Verantwortlichkeiten
Die DomainResolver-Middleware hat aktuell zu viele Aufgaben. Eine Aufteilung verbessert die Lesbarkeit, Wartbarkeit und Einhaltung des Single-Responsibility-Prinzips.
Vorschlag für neue Middleware-Struktur:
-
InitializeDomainContext(Neue Middleware):- Diese Middleware läuft sehr früh (kann global oder am Anfang der
web-Gruppe stehen). - Ihre einzige Aufgabe ist es, den
DomainContextzu initialisieren, indem sieapp(DomainContext::class)aufruft. Sie führt keine Session-Operationen oder Umleitungen durch. Dies stellt sicher, dass der Kontext für alle nachfolgenden Teile der Anwendung (auch andere Middleware) verfügbar ist.
- Diese Middleware läuft sehr früh (kann global oder am Anfang der
-
HandleDomainLogic(UmbenannterDomainResolver):- Diese Middleware läuft nach
StartSession. - Sie nutzt den bereits initialisierten
DomainContext. - Aufgaben:
- Umleitung bei
isUnknown(). - Validierung des
UserShop(aktiv, bezahlt etc.). - Persistierung des
UserShop-Kontexts in der Session. Die Logik hierfür wird verfeinert, um den Shop-Kontext über Domain-Grenzen hinweg intelligent zu erhalten. Zum Beispiel wird deruser_shopnicht mehr gelöscht, nur weil man diemain-Domain besucht. Er wird nur überschrieben, wenn ein neuer Shop-Kontext explizit gesetzt wird.
- Umleitung bei
- Diese Middleware läuft nach
Schritt 3: Vereinfachung des Session-Handlings
Die setupLegacyContext-Methode wird überarbeitet. Das Ziel ist ein klares und vorhersehbares Verhalten:
- Auf einer User-Shop-Domain: Der
UserShopwird in die Session geschrieben. - Auf einer Nicht-Shop-Domain (
crm,portal,checkout,main): Die Session wird nicht angerührt. Der bestehendeUserShopaus der Session bleibt erhalten, sodass eine Rückkehr zum Shop jederzeit möglich ist. - Wechsel zu einem anderen User-Shop: Der neue
UserShopüberschreibt den alten Wert in der Session.
4. Vorteile der neuen Architektur
- Stabilität: Das Session-Problem wird an der Wurzel behoben, indem die Middleware-Reihenfolge korrigiert wird.
- Klarheit: Die Verantwortlichkeiten sind sauber getrennt. Eine Middleware für die Kontext-Initialisierung, eine für die Domain-Logik.
- Wartbarkeit: Einfacher zu verstehen und zu erweitern. Das
TECH-DEBTinsetupLegacyContextwird reduziert. - Performance: Die Logik zur Domain-Analyse im
DomainServiceProviderwird nur einmal ausgeführt, wenn der Kontext das erste Mal benötigt wird (lazy-loading), was beibehalten wird.
Die folgenden Dateien in diesem Ordner enthalten eine beispielhafte Implementierung dieses Vorschlags.