Lektion 4.3.7 hat das Muster Strangler Fig im Kleinen gezeigt: Der Planer der Termine blieb als Fassade stehen, dahinter wuchs das Aggregat, und Charakterisierungstests bewiesen nach jedem Schritt, dass sich am Verhalten nichts geändert hatte. Lektion 4.6.5 hat an der Grenze zu TED einen Anti-Corruption Layer gesetzt, der das fremde Modell draußen hält. Diese Lektion bringt beides zusammen, im Großen: ein ganzes Altsystem mit eigener Datenbank, eine Fassade, die Anfragen weiterleitet, und ein Umzug, der Funktion für Funktion geschieht, während beide Systeme laufen.

Der Anlass ist erfunden, aber typisch. Das IT-Büro der Kladde hat ein kleineres Büro übernommen. Dessen alte Kundenverwaltung, die „Bürodatenbank“, läuft weiter, und andere Programme dort rufen sie über HTTP auf: ein Programm, das Serienbriefe druckt, und die Anzeige der Termine am Empfang. Diese Aufrufer lassen sich nicht an einem Tag umstellen. Die Inhaberin will trotzdem, dass die Kunden des übernommenen Büros bald in der Kladde stehen.

Sie bauen in dieser Lektion in einem Übungsordner drei kleine Programme: das Altsystem, die Kladde im Kleinen und eine Fassade mit YARP. Dann ziehen Sie eine Funktion um, gleichen die Daten ab und gehen den Rückweg. In der Kladde selbst ändert sich nichts; die Übungen geben Ihnen den Plan und das Werkzeug für den Tag, an dem Ihr Büro so ein Altsystem wirklich mitbringt.

Das Muster im Großen

Microsofts Seite zum Muster Strangler Fig beschreibt vier Phasen:

  1. Eine Fassade, ein Proxy, steht zwischen den Aufrufern, dem Altsystem und dem neuen System. Anfangs leitet sie fast alles an das Altsystem.
  2. Schritt für Schritt leitet sie mehr Anfragen an das neue System, das mit jedem Schritt eine Funktion mehr übernimmt.
  3. Hängt nichts mehr am Altsystem, wird es abgeschaltet. Die Fassade leitet alles an das neue System.
  4. Die Fassade wird entfernt, und die Aufrufer sprechen direkt mit dem neuen System. Microsoft lässt auch zu, die Fassade als Adapter für alte Aufrufer zu behalten.

Die Aufrufer merken davon nichts: Sie benutzen dieselbe Schnittstelle wie vorher. Microsoft nennt dazu eine Reihe von Punkten, die bei einem großen Umzug zählen:

  • Gemeinsame Daten und Dienste. Brauchen beide Systeme dieselben Daten, müssen beide während des Umzugs daran kommen.
  • Abhängigkeiten in beide Richtungen. Das neue System ruft Funktionen, die noch im alten stecken, und das alte ruft Funktionen, die schon umgezogen sind. Dazwischen gehört ein Anti-Corruption Layer, damit das neue System die Begriffe des alten nicht übernimmt.
  • Die Fassade hält Schritt mit dem Umzug, und sie darf weder zum einzigen Ausfallpunkt noch zum Engpass werden.
  • Eine Übergangsarchitektur. Fassade, Abgleich und doppelte Verträge kosten Betrieb, solange der Umzug läuft. Das ist der Preis für das kleinere Risiko.
  • Ein Altsystem, das sich nicht ändern lässt, bekommt seine Änderungen manchmal über die Datenbank mit, etwa über Change Data Capture.

Ungeeignet ist das Muster, wenn sich die Anfragen an das Altsystem nicht abfangen lassen, wenn es weder Quellcode noch einen anderen Ansatzpunkt wie die Datenbank gibt, wenn das System klein und schnell ersetzt ist, oder wenn das Alte sehr schnell ganz weg muss.

YARP als Fassade: so beschreibt es Microsoft

Für den Umzug einer großen Anwendung von ASP.NET auf ASP.NET Core empfiehlt Microsoft genau dieses Muster. Die Übersichtsseite zur Migration sagt es ausdrücklich: Die inkrementelle Migration ist eine Umsetzung des Musters Strangler Fig, gedacht für große Anwendungen, die während des Umzugs in Betrieb bleiben müssen. Der erste Schritt ist eine neue ASP.NET-Core-Anwendung neben der alten, die mit YARP (Yet Another Reverse Proxy) an die alte weiterleitet. Eine Route, die die neue Anwendung selbst kennt, beantwortet sie selbst; alle anderen Anfragen gehen über eine Rückfallroute an die alte Anwendung. Danach räumt man technische Schulden auf, klärt Querschnittsthemen wie Anmeldung und Sitzungen zwischen beiden Anwendungen und hebt erst dann Bibliotheken an, und zwar nur die, die die gerade umziehenden Routen brauchen, von unten nach oben durch den Abhängigkeitsbaum.

Dort ist die neue Anwendung selbst die Fassade. In dieser Lektion steht die Fassade für sich, als eigenes kleines Programm vor zwei Anwendungen: Die Kladde ist schon eine fertige Anwendung, und welche Funktion wohin geht, soll in einer Konfiguration stehen, nicht im Code eines der beiden Systeme. Beide Formen sind dasselbe Muster.

YARP ist eine Bibliothek für ASP.NET Core, das Paket heißt Yarp.ReverseProxy. Die Version 2.3.0 unterstützt .NET 8 und später. Eine Fassade besteht aus Routen und Clustern:

  • Eine Route hat einen Namen, eine Bedingung (Match: ein Pfad oder Hostnamen, dazu auf Wunsch Methoden, Header, Abfrageparameter) und den Namen eines Clusters.
  • Ein Cluster hat ein oder mehrere Ziele (Destinations) mit ihrer Adresse.
  • Passen mehrere Routen, gewinnt die genaueste, nach den Regeln des Routings von ASP.NET Core; mit Order lässt sich die Reihenfolge festlegen, kleinere Werte zuerst.
  • Liest YARP seine Konfiguration aus einer Datei, übernimmt es Änderungen ohne Neustart. Nur geänderte Routen und Cluster werden ersetzt, auf einen Schlag, und nur für neue Anfragen; laufende Anfragen sind nicht betroffen. Ist die neue Konfiguration fehlerhaft, protokolliert YARP den Fehler und behält die letzte gültige.

Der letzte Punkt macht aus einem Umzug eine Änderung an einer Datei, die sich in einem Pull Request prüfen und in einem zweiten zurücknehmen lässt.