Modul 4.11 hat die Architekturstile nebeneinandergelegt und in Lektion 4.11.2 gefragt, wann sich ein eigener Dienst lohnt. Dieses Modul macht es: Der Kontext Ausschreibungen wird der erste eigene Dienst der Kladde. Er hat einen eigenen Rhythmus (den nächtlichen Import), eine eigene Last und kaum Schreibzugriffe anderer, und seine Grenze im Code steht seit Lektion 4.3.6. Das Modul baut auf zwei Modulen auf: auf 4.6 (Outbox, Inbox, Prozessmanager), weil Dienste über Nachrichten reden, und auf 4.7 (Netz, Identität), weil jeder Aufruf jetzt über das Netz geht. Am Ende, in Lektion 4.12.8, legen Sie die Microservices neben die virtuellen Akteure aus Modul 4.5.

Diese erste Lektion klärt, wo eine Dienstgrenze hingehört und wie groß ein Dienst sein darf. Dann lösen Sie die Ausschreibungen heraus, so, dass kein Aufrufer im Monolithen es merkt.

Ein Dienst je Bounded Context

Die wichtigste Regel steht in Microsofts Leitfaden zu Microservices im Azure Architecture Center in einem Satz: Ein Microservice ist nicht kleiner als ein Aggregat und nicht größer als ein Bounded Context. Daraus folgen zwei Dinge:

  • Ein Dienst mischt keine Modelle. Mischt ein Dienst zwei Bounded Contexts, mischt er zwei Sprachen und zwei Modelle. Dann stimmt die Domänenanalyse aus Modul 4.2 nicht, nicht der Code.
  • Ein Kontext darf mehrere Dienste haben, nicht umgekehrt. Hat der Kontext Ausschreibungen eines Tages einen Importdienst und einen Suchdienst, ist das in Ordnung, solange beide dasselbe Modell sprechen und einem Team gehören.

Die verbreitetste falsche Grenze ist ein Dienst je Tabelle oder Entität: ein Kontaktdienst, ein Angebotsdienst, ein Angebotspositionendienst, ein Preisdienst, jeder mit Anlegen, Lesen, Ändern, Löschen. Das sieht ordentlich aus und ist das Gegenteil eines Schnitts nach Fachlichkeit:

Anwendungsfall „Angebot zu einer Ausschreibung anlegen“ Schnitt nach Entität Schnitt nach Kontext
Aufrufe über das Netz Ausschreibung lesen, Kontakt lesen, Angebot anlegen, je Position einmal Position anlegen und Preis lesen Ausschreibung lesen; das Angebot entsteht mit seinen Positionen in einem Aufruf an sich selbst
wo die Regel „Summe ab Grenze braucht zweite Freigabe“ steht verteilt: Angebotsdienst und Positionendienst müssen sich abstimmen im Aggregat Quote (Lektion 4.3.2)
Transaktion keine gemeinsame: eine halb angelegte Position bleibt liegen eine je Aggregat, wie bisher
was beim Ausfall eines Dienstes geschieht kein Angebot mehr möglich, auch wenn nur der Preisdienst fehlt ohne Ausschreibungsdienst fehlt nur der Bezug zur Ausschreibung

Ein Schnitt nach Entitäten erzeugt gesprächige Aufrufe (chatty calls): Für einen Fall braucht es viele kleine Anfragen, jede mit Netzlaufzeit und eigenem Ausfall. Die Aggregate sind zerrissen, ihre Invarianten liegen über Dienste verteilt. Am Ende steht ein verteilter Monolith: alle Nachteile der Verteilung, keiner ihrer Vorteile, denn ausgeliefert werden kann wieder nur alles zusammen.