1. **Dokumentation der Architektur:**
- Vervollständigen Sie die C4-Diagramme im docs-Verzeichnis
- Dokumentieren Sie die wichtigsten Architekturentscheidungen in ADRs
2. **Redis-Integration finalisieren:**
- Implementieren Sie die verteilte Cache-Lösung für die Offline-Fähigkeit
- Nutzen Sie Redis Streams für das Event-Sourcing
4.7 KiB
ADR-0007: API-Gateway-Muster
Status
Akzeptiert
Kontext
Mit unserer Microservices-Architektur (ADR-0003) standen wir vor mehreren Herausforderungen im Zusammenhang mit der Client-Service-Kommunikation:
- Clients müssten die Standorte und Schnittstellen mehrerer Dienste kennen
- Verschiedene Clients (Web, Desktop, Mobil) müssten mehrere Aufrufe an verschiedene Dienste tätigen
- Authentifizierung und Autorisierung müssten konsistent über alle Dienste hinweg implementiert werden
- Querschnittsbelange wie Rate-Limiting, Logging und Monitoring müssten in jedem Dienst implementiert werden
- API-Versionierung und Abwärtskompatibilität müssten über alle Dienste hinweg verwaltet werden
- Die Netzwerksicherheit wäre komplexer, wenn mehrere Dienste direkt exponiert würden
Wir benötigten eine Lösung, die die Client-Service-Kommunikation vereinfachen und gleichzeitig diese Herausforderungen adressieren würde.
Entscheidung
Wir haben uns entschieden, das API-Gateway-Muster mit Ktor als Framework zu implementieren. Das API-Gateway dient als einziger Eingangspunkt für alle Client-Anfragen und bietet die folgenden Funktionen:
- Anfrage-Routing: Leitet Anfragen an die entsprechenden Microservices weiter
- Authentifizierung und Autorisierung: Integriert sich mit Keycloak (ADR-0006), um Benutzer zu authentifizieren und Tokens zu validieren
- Rate-Limiting: Verhindert Missbrauch durch Begrenzung der Anzahl von Anfragen von einem einzelnen Client
- Anfrage/Antwort-Transformation: Transformiert Anfragen und Antworten nach Bedarf für verschiedene Clients
- Logging und Monitoring: Bietet zentralisiertes Logging und Monitoring aller API-Anfragen
- Caching: Speichert Antworten im Cache, um die Leistung zu verbessern
- API-Dokumentation: Hostet OpenAPI-Dokumentation für alle Dienste
- Service-Discovery: Entdeckt Dienstinstanzen dynamisch
Unsere Implementierung umfasst:
- Ein Ktor-basiertes API-Gateway, das als containerisierter Dienst bereitgestellt wird
- Integration mit Keycloak für Authentifizierung und Autorisierung
- Benutzerdefinierte Plugins für Rate-Limiting, Logging und Monitoring
- OpenAPI-Dokumentationsgenerierung
- Service-Discovery-Integration
Konsequenzen
Positive
- Vereinfachte Client-Entwicklung: Clients müssen nur mit einem einzigen Endpunkt kommunizieren
- Konsistente Sicherheit: Authentifizierung und Autorisierung werden konsistent gehandhabt
- Zentralisierte Querschnittsbelange: Rate-Limiting, Logging und Monitoring werden einmal implementiert
- Verbesserte Sicherheit: Interne Dienste werden nicht direkt Clients ausgesetzt
- Flexibilität: Das Gateway kann Anfragen und Antworten für verschiedene Clients anpassen
Negative
- Single Point of Failure: Das Gateway wird zu einer kritischen Komponente, die hochverfügbar sein muss
- Leistungs-Overhead: Anfragen durchlaufen einen zusätzlichen Netzwerk-Hop
- Komplexität: Das Gateway muss eine breite Palette von Funktionalitäten handhaben
- Entwicklungs-Engpass: Änderungen am Gateway können Koordination über Teams hinweg erfordern
Neutral
- Deployment-Überlegungen: Das Gateway muss angemessen bereitgestellt und skaliert werden
- Versionierungsstrategie: API-Versionierung muss immer noch verwaltet werden, wenn auch an einem Ort
Betrachtete Alternativen
Direkte Client-zu-Service-Kommunikation
Wir haben in Betracht gezogen, Clients die direkte Kommunikation mit Diensten zu ermöglichen. Dies hätte den Netzwerk-Hop durch das Gateway eliminiert, hätte aber die Client-Entwicklung komplexer gemacht und hätte die Implementierung von Querschnittsbelangen in jedem Dienst erfordert.
Backend for Frontend (BFF)-Muster
Wir haben die Implementierung separater Backend for Frontend (BFF)-Dienste für jeden Client-Typ in Betracht gezogen. Dies hätte mehr clientspezifische Optimierungen ermöglicht, hätte aber den Entwicklungs- und Betriebsaufwand erhöht.
Service Mesh
Wir haben die Verwendung eines Service Mesh wie Istio oder Linkerd zur Handhabung der Service-zu-Service-Kommunikation in Betracht gezogen. Dies hätte viele der gleichen Vorteile für die Service-zu-Service-Kommunikation geboten, hätte aber die Herausforderungen der Client-zu-Service-Kommunikation nicht so effektiv adressiert.