7 KiB
7 KiB
Domain Management System - Optimierte Architektur
Übersicht
Dieses optimierte Domain Management System löst die Session-Probleme des aktuellen Systems und bietet eine saubere, wartbare Architektur für Multi-Domain-Anwendungen.
Hauptprobleme der aktuellen Implementierung
- Session-Konflikte: DomainResolver wird zu früh ausgeführt, bevor die Session-Middleware verfügbar ist
- Zwei Sessions: Dadurch werden zwei separate Sessions erstellt
- Komplexe Logik: Domain-Auflösung und Session-Management sind eng gekoppelt
- Performance: Ineffizientes Caching und wiederholte DB-Abfragen
Neue Architektur
Kernkomponenten
├── DomainResolver (Middleware) - Reine Domain-Auflösung
├── DomainContext (DTO) - Unveränderlicher Domain-Kontext
├── DomainService - Zentraler Service für Domain-Logik
├── SessionHandler - Event-basiertes Session-Management
├── RouteService - Domain-aware Route-Loading
└── CacheManager - Optimiertes Caching
Middleware-Reihenfolge (Behoben)
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\App\Http\Middleware\DomainResolver::class, // ✅ Nach Cookies, vor Session
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\DomainSessionHandler::class, // ✅ Nach Session-Start
// ... weitere Middleware
]
Hauptverbesserungen
1. Session-Problem gelöst
- DomainResolver: Läuft nach Cookie-Encryption, aber vor Session-Start
- DomainSessionHandler: Verarbeitet Session-Updates nach Session-Initialisierung
- Event-basierte Kommunikation: Domain-Änderungen werden als Events behandelt
2. Saubere Trennung der Verantwortlichkeiten
- DomainResolver: Nur Domain-Auflösung und Kontext-Erstellung
- DomainSessionHandler: Nur Session-Management
- DomainService: Reine Geschäftslogik
3. Performance-Optimierungen
- Intelligentes Caching: Mehrere Cache-Schichten
- Lazy Loading: UserShop-Daten werden nur bei Bedarf geladen
- Batch-Operations: Mehrere Domain-Validierungen in einem Durchgang
4. Domain-Types
enum DomainType: string {
case MAIN = 'main'; // mivita.care
case SHOP = 'shop'; // mivita.shop
case CRM = 'crm'; // my.mivita.care
case PORTAL = 'portal'; // in.mivita.care
case CHECKOUT = 'checkout'; // checkout.mivita.care
case USER_SHOP = 'user-shop'; // {slug}.mivita.care
case UNKNOWN = 'unknown';
}
Implementierung
DomainResolver (Neue Middleware)
class DomainResolver
{
public function handle(Request $request, Closure $next)
{
// 1. Domain parsen und Context erstellen
$context = $this->resolveDomain($request->getHost());
// 2. Context in Request speichern (nicht Session!)
$request->merge(['domain_context' => $context]);
// 3. Session-Domain setzen für Cookies
$this->setSessionDomain($context);
// 4. Domain-Changed Event auslösen (falls nötig)
if ($this->domainChanged($context)) {
event(new DomainChangedEvent($context));
}
return $next($request);
}
}
DomainSessionHandler (Neue Middleware)
class DomainSessionHandler
{
public function handle(Request $request, Closure $next)
{
$response = $next($request);
// Session nur updaten, wenn Domain-Context verfügbar
if ($context = $request->get('domain_context')) {
$this->updateSessionForDomain($context);
}
return $response;
}
private function updateSessionForDomain(DomainContext $context): void
{
// UserShop in Session setzen/behalten
if ($context->isUserShop()) {
Session::put('user_shop', $context->userShop);
Session::put('user_shop_domain', $context->host);
}
// Session-Domain aktualisieren
Config::set('session.domain', $this->getSessionDomain($context));
}
}
DomainService (Optimierte Version)
class DomainService
{
public function resolveDomain(string $host): DomainContext
{
// 1. Host normalisieren
$normalizedHost = $this->normalizeHost($host);
// 2. Domain-Info parsen
$domainInfo = $this->parseDomain($normalizedHost);
// 3. Domain-Type bestimmen
$type = $this->determineDomainType($domainInfo);
// 4. UserShop laden (nur bei Bedarf)
$userShop = $this->loadUserShopIfNeeded($type, $domainInfo);
return new DomainContext($type, $normalizedHost, $domainInfo['subdomain'], $userShop);
}
private function loadUserShopIfNeeded(DomainType $type, array $domainInfo): ?UserShop
{
if (!$type->isUserShop()) {
return null;
}
return $this->getUserShop($domainInfo['subdomain']);
}
}
Migration Guide
Schritt 1: Neue Dateien hinzufügen
# Neue Middleware
cp dev/subdomain-optimization-grok/src/Middleware/DomainResolver.php app/Http/Middleware/
cp dev/subdomain-optimization-grok/src/Middleware/DomainSessionHandler.php app/Http/Middleware/
# Neue Services
cp dev/subdomain-optimization-grok/src/Services/DomainService.php app/Services/
cp dev/subdomain-optimization-grok/src/Services/DomainCacheManager.php app/Services/
# Neue Domain-Klassen
cp dev/subdomain-optimization-grok/src/Domain/DomainContext.php app/Domain/
cp dev/subdomain-optimization-grok/src/Domain/DomainType.php app/Domain/
Schritt 2: Kernel.php aktualisieren
'web' => [
// ... existing middleware ...
\App\Http\Middleware\DomainResolver::class, // Nach Cookies
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\DomainSessionHandler::class, // Nach Session
// ... rest of middleware ...
],
Schritt 3: DomainServiceProvider aktualisieren
// Alte DomainResolver-Middleware entfernen
// Neue Services registrieren
Vorteile der neuen Architektur
- Session-Konflikte behoben: Klare Trennung zwischen Domain-Auflösung und Session-Management
- Bessere Performance: Optimiertes Caching und Lazy Loading
- Wartbarkeit: Klare Trennung der Verantwortlichkeiten
- Testbarkeit: Jede Komponente kann isoliert getestet werden
- Skalierbarkeit: Einfache Erweiterung um neue Domain-Types
- Event-Driven: Lose Kopplung durch Events
Tests
# Unit Tests
php artisan test tests/Unit/Domain/
# Feature Tests
php artisan test tests/Feature/DomainRouting/
# Integration Tests
php artisan test tests/Feature/SessionDomainSwitching/
Monitoring
Das neue System integriert sich nahtlos mit Laravel's Logging und Monitoring:
// Domain-Resolution Metrics
Log::channel('domain')->info('Domain resolved', [
'host' => $host,
'type' => $context->type,
'resolution_time' => $time,
'cache_hit' => $cacheHit
]);
Fazit
Diese optimierte Architektur löst alle identifizierten Probleme und bietet eine solide Grundlage für zukünftige Erweiterungen des Domain-Systems.