Shownotes & Links
- Self-contained Systems Homepage
- Demo eines Self-contained Systems im Versicherungskontext
- Beschreibung der Demo
- Blog Post: Transklusion in Self-Contained Systems
- Demo: ESI for Frontend Integration
- Demo: jQuery for Frontend Integration
Transkript
Eberhard Wolff: Willkommen zum innoQ Podcast. Mein Name ist Eberhard Wolff, ich sitze hier mit Till und Falk, unseren Kollegen. Wir sind gerade auf dem innoQ-Event in der Schweiz, kurz vor Weihnachten. Wir wollen sprechen über Self-contained Systems aus einer Frontend Perspektive und Frontend Integration. Wollt ihr euch kurz vorstellen?
Falk Hoppe: Ja hi, ich bin Falk, ich bin Senior Consultant bei der innoQ. Ich beschäftige mich hobbymäßig relativ viel mit dem Bereich Frontend und das hat sich jetzt halt auch nach und nach immer weiter im professionellen Umfeld auch belohnt.
Till Schulte-Coerne: Ich bin Till Schulte-Coerne, ich bin auch seit längerem bei der innoQ und ich beschäftige mich mit Softwareentwicklung, Architektur und eben insbesondere auch mit dem Frontend-Architekturthema – seit letzter Zeit.
Eberhard Wolff: Genau. Fangen wir einfach an mit dem grundsätzlichen Thema, Modularisierung. Warum wollen wir denn überhaupt Systeme zerschneiden.
Till Schulte-Coerne: Ja, warum wollen wir das tun? Damit wir uns nicht gegenseitig auf den Füßen stehen. Also wie wir es tun, ist natürlich immer so eine Frage, aber das, was wir letzten Endes erreichen wollen ist, dass wir Systeme bauen können, ohne irgendwelchen riesigen Koordinationsaufwand mit anderen zu treiben. Und ja, welchen Ansatz man da auch immer wählt, ist natürlich immer die Frage. Ich glaube, in diesem Kontext wollen wir ja primär um den Ansatz mit Self-contained Systems reden, was eben dann einfach bedeutet, dass ich letzten Endes einen relativ großen Schnitt wahrscheinlich ansetze. Dann aber eben wirklich dafür sorge, dass das Ding dann eben auch – wie der Name schon sagt – komplett self-contained ist, und seine gesamte Logik, und alles was so darum herum ist.
Falk Hoppe: Genau, viele Dinge, die wir da ja vorfinden, sind eigentlich auch die Sachen, die ursprünglich mal in diesem Microservice-Feld anskizziert wurden. Wir wollen die Sachen unabhängig voneinander releasen können, wir wollen verschiedene Softwarestände benutzen, wir möchten sprachunabhägig bleiben. Wir möchten Systeme auch teilweise ersetzen können, ohne dass andere Systeme davon betroffen sind, und so weiter.
Eberhard Wolff: Jetzt haben wir irgendwie schon gesprochen, über Self-contained Systems – kann jemand von euch noch mal definieren, was das eigentlich genau ist?
Falk Hoppe: Ein Self-contained System ist eigentlich so ein bisschen der große Bruder eines Microservices, vielleicht. Also, Microservice hat man häufig – also die Idee dahinter finde ich persönlich sehr sehr gut. Allerdings ist der infrastrukturelle Overhead, den man da so hat, bei der Koordinierung von vielen, vielen kleinen Services doch, glaube ich, sehr stark unterschätzt worden am Anfang, und Self-contained Systems bieten quasi so eine Domänen-Klammer um ein Set von Microservices oder um einen kleineren “Monolithen”.
Till Schulte-Coerne: Was mir eben auch dabei relativ wichtig ist, ist, dass es eben eigentlich den Full-Stack-Ansatz beinhaltet. Also, das heißt eben vom Frontend bis letzten Endes wirklich in die Persistenzebene alles in der Zuständigkeit des jeweiligen Teams – hoffentlich, wenn alles gut läuft – ist. Und das ist eben etwas, was ich persönlich daran sehr wichtig finde, weil ich mich halt auch zum Beispiel, wenn die klassische Trennung zwischen Backend und Frontend damit übersetzt wird, da brauche ich zwei unterschiedliche Teams – da frage ich mich immer, wie hoch ist denn die Wahrscheinlichkeit, dass ihr tatsächlich einen neuen Featurerequest reinkriegt, der nur eins dieser beiden Teams betrifft, ja? Üblicherweise, wenn ich neue Dinge umsetze, dann betrifft das normalerweise natürlich irgendeine Logik, die vorher noch nicht da war, im Backend. Aber eben normalerweise auch die Repräsentation dieser Logik im Frontend. Deswegen ist das für mich ganz wichtig, dass das letzten Endes aus einer Hand kommt.
Eberhard Wolff: Das heißt also, was wir jetzt gerade diskutiert haben, ist, dass ist eher ein grobgranularer Schnitt, und etwas, was auch sich um die organisatorischen Aspekte kümmert. Also, dass wir irgendwie sagen, einem Team gehört ein SCS. Also, dass eben ein Team sich um ein SCS kümmert. Irgendwas, was wir jetzt vergessen haben?
Falk Hoppe: Was ich da sehr wichtig finde, ist halt eben, dass das halt auch ne Verantwortungsklammer ist. Ich isoliere mein System von den Fachlichkeiten anderer Teams. Das heißt, ich möchte gerne für das, was ich ausliefere, verantwortlich sein, von Entwicklung bis Produktion. Das heißt halt eben auch, dass ich versuchen möchte, mich soweit wie möglich von den anderen Systemen zu entkoppeln, oder lose Kopplung aufzubauen.
Eberhard Wolff: Ok. Ansonsten, vielleicht an der Stelle noch kurz der Hinweis, also es gibt eine Webseite, scs-architecture.org, da steht’s auch genau drin was ein Self-contained System ist. Da kann man die Definition auch nochmal nachlesen.
Damit ist auch klar, ein Frontend gehört eben zu einem Self-contained System. Das führt ja jetzt zu der Frage, soll jetzt jedes Self-contained System selber entscheiden, wie es sich präsentiert. Also typischerweise würde ich ja jetzt ein großes System bauen, ich würde es aufteilen in mehrere Self-contained Systems, vielleicht soll das für den Kunden oder für den Benutzer gar nicht transparent sein, dass das mehrere Self-contained Systems gibt, die dahinter stecken. Das führt jetzt zu der Frage, wie ich damit umgehe, dass ich irgendwie die Präsentation dann vielleicht doch einheitlich haben will, oder sowas.
Till Schulte-Coerne: Genau, das ist halt – wir wollen das schneiden, aus unserer einzelnen, oder aus unserer Perspektive als Entwickler und Architekten sind wir am Schnitt interessiert. Jemand, der unsere Systeme verwendet, ist natürlich nicht daran interessiert, permanent von dem einen Client in den anderen Client reinzuspringen. Das heißt, ein wichtiger Bestandteil oder aus meiner Sicht fast der wichtigste Bestandteil bei dieser ganzen Thematik ist eben die Frage danach, wenn ich irgendetwas zerschnitten habe, was für mich gut ist, wie kriege ich es dann nacher wieder so zusammen, dass es auch für den, der es nachher benutzt, wieder gut wird. Und wenn wir das jetzt eben auf den Frontend-Aspekt sozusagen beziehen – das hat natürlich Auswirkungen in die Datenhaltung, das hat Auswirkungen auf Backendebene, mache ich irgendwie REST, mache ich Webservices, was weiß ich, ich kann ja meistens nicht meine Arbeit völlig isoliert von Informationen und Funktionalität von anderen betreiben. Aber wir wollen ja heute über das Frontend reden, und beim Frontend, wie du schon sagst, geht es halt primär wirklich auch um Sachen wie ‘Look and Feel’, ja?. Ich erwarte einfach, dass wenn die Seite vorher grün war, ein grünes Logo oben drüber hatte, dass es danach immer noch so ist. Aber das geht eben auch viel weiter, das geht eben so weit, dass z.B. es irgendwie komisch wäre, wenn sich permanent die Hauptnavigation ändern würde. Nur weil die einen gerade da irgendwas anderes reingeschrieben haben als die anderen. Das bedeutet – oder es bezieht sich eben auch auf weitere Dinge, wie z.B. ich kann ja nicht jedes Mal, nur wenn ich eine Information brauche, das eine System verlassen, um in das andere zu kommen. Also ich brauche offensichtlich irgendwelche Mechanismen, um auch im Frontend Funktionalität und Informationen von anderen Systemen zu integrieren.
Falk Hoppe: Genau. Also, ich denke, wir können das ganz grob darin unterteilen, dass wir im Prinzip statische Inhalte haben. Da gehören Dinge rein, wie teilweise die Navigation, da gehe ich auf jeden Fall d’accord. In den meisten Anwendungen ist es eigentlich nicht notwendig, dass die Hauptnavigation dynamische Inhalte beinhaltet. Also, die wirklich aus einem CMS oder ähnlichem kommen. Aber halt eben ganz klassischerweise der Header, ganz häufig der Footer, die Styles, wie die Seitennavigation angeordnet wird, wie das responsive Verhalten sich auswirkt von dem Page Layout und ähnliche Geschichten. Aber halt eben auch die dynamische Klammer, wenn ich aus einem System Inhalte aus einem anderen System einbetten möchte, dann muss ich dafür irgendwie einen Mechanismus bieten.
Till Schulte-Coerne: Um zu den statischen Inhalten vielleicht noch zu ergänzen: Ich würde natürlich auch erwarten, wenn der Button zum Abschicken des Formulars in dem einen System grün aussieht und in dem anderen blau, das wäre natürlich auch nicht optimal. UI-Elemente, die letzten Endes für unterschiedliche Systeme, die im selben Kontext sind, relevant sind, die müssen natürlich auch gleich aussehen. Wir wollen ja nicht irgendwie UIs bauen, die einfach nicht benutzbar sind, sondern wir erwarten natürlich, dass es nach außen hin wirkt wie ein System und dass ist eine Problemstellung, die wir natürlich lösen müssen.
Falk Hoppe: Gerade aus der Frontend-Perspektive ist da ja halt auch eben heute das nicht mehr getan, indem wir einfach nur ein paar Styles rüberschieben. Wir reden da ja halt auch eben von dem Verhalten von solchen Komponenten. Und auch das ist in der Regel was, was wir zentral ausliefern sollten.
Eberhard Wolff: Das heißt also, wir reden halt hier über statische Inhalte und dynamische Inhalte, mehr als Look and Feel, sondern eben auch das Verhalten teilweise. Ich glaube ein wichtiger Hinweis, weil wir das in der weiteren Diskussion ausblenden werden, ist, dass wir hier tatsächlich nur über Frontend Integration reden. Also es gibt auch ganz viel, wo man noch über Backend Integration reden kann, wie Self-contained Systems sich da integrieren, und das ist auch eine weitere Möglichkeit.
Vielleicht an der Stelle so eine kurze Frage: Würdet ihr sagen, dass Frontend Integration der bevorzugte Weg der Intergration bei Self-contained Systems ist? Also das man irgendwie sagt, das ist das, was wir eigentlich anstreben?
Till Schulte-Coerne: Es ist auf jeden Fall ein sehr eleganter Weg. Also, es ist, glaube ich, relativ verheerend, wenn man letzten Endes sich so die klassische Backend Welt anschaut und man eben Integration automatisch und reflexhaft mit Backend-Aufrufen übersetzt. Das hat alles irgendwie seine Berechtigung. Wenn man eben intelligent und gut im Frontend integriert, dann ist das eben üblicherweise auch eine sehr leichtgewichtige Integration – zumindest wenn man es richtig macht. Da kommen wir ja gleich noch zu. Aber das sind dann eben wirklich Dinge, wo man auch, glaube ich, sehr viel gewinnen kann. Die man einfach nicht ausblenden sollte. Natürlich kann ich jedes Mal, wenn ich in irgendeinem UI eine Information aus einem anderen System anzeigen muss, mir die über einen Backend- Call synchron beschaffen. Aber das ist vielleicht nicht das Optimale. Das geht natürlich auch. Das, was eben wichtig ist, ist dabei, dass man seine Optionen kennt, und dann muss man halt leider, so ist das halt in der Softwarearchitektur und -entwicklung, die richtige Option aus einer riesigen Palette von Optionen auswählen. Das kann man keinem ersparen. Mir ist halt wichtig, dass diese Option, dass klar ist, dass diese Optionen bestehen. Gerade bei Webanwendungen. Bei anderen UI-Technologien bestehen sie eben gerade nicht. Also irgendwie hinzugehen und – ich mein', das geht auch alles irgendwie, irgendwelche Rich- Clients dynamisch zusammenzufügen, ist einfach nicht so leicht, wie irgendwie eine UI im Web aus mehreren Bestandteilen.
Falk Hoppe: Genau, es ist halt nativer Bestandteil des Webs, dass man UIs miteinander integriert, dass man komplett verschiedene Domänen miteinander eben verbindet.
Eberhard Wolff: Also wir haben da ein zusätzliches Werkzeug, was, glaube ich, tatsächlich oft in der klassischen eher Backend-Architektur auch übersehen wird. Trotzdem ist es ja jetzt so, wir haben irgendwie darüber diskutiert, Self- contained Systems sind am Ende des Tages auch Module, die halt irgendwie auch zusammengehören, und wir haben jetzt auch gerade gesagt, dass die auch irgendwie sich einheitlich anfühlen sollen. Wie drücken wir das denn jetzt aus? Wir haben ja auf der anderen Seite das Thema, was wir gerade auch diskutiert haben, dass wir eigentlich eine weitgehende Unabhängigkeit von Teams zu Komponenten haben wollen, wie bekommen wir das hin? Also wie sagen wir, das sind die Sachen, die jeweils irgendjemand entscheiden darf, oder die halt irgendwie jede Komponente anders macht. Was sind die zentralen Dinge?
Till Schulte-Coerne: Was halt aber wichtig ist, wenn ich irgendwelche Dinge zerschneide, ist offensichtlich, dass ich die Regeln definiere, wie ich sie reintegriere auf ganz verschiedenen Ebenen. Ich glaube, ihr nennt das meistens, ihr kennt euch ja damit fast besser aus als wir, wahrscheinlich, Makro- und Mikroarchitektur. Das finde ich sehr gute Begriffe. Ich weiß nicht, ob man es vielleicht nicht auch Integrationsarchitektur und innere Architektur nennen kann. Ich rede mal über Makro und Mikro. Mikroarchitektur ist das, was man leider viel zu häufig sieht, auf 'nem viel zu großen Scope. Nämlich, “Wir benutzen Java in der und der Version und das und das Webframework”, das sind aber eigentlich Entscheidungen, die ich in der Ebene global gar nicht treffen brauche, zum Beispiel, nur um Systeme zerschneiden zu können. Ich will natürlich irgendwie entscheiden, dass ich in meinem Unternehmen Java mache und nicht dreizehn Programmiersprachen durcheinander schmeiße. Aber die spielen aus diesem reinen Integrationsaspekt eigentlich keine Rolle. Das sind andere Treiber, die ich da habe. Das sind auch üblicherweise andere Lebenszyklen, die ich da berücksichtigen muss, als wenn ich eben über diese Integrations- diese Makrothemen rede. Auf so einer Makroebene könnte dann eben sowas sein wie, “Wenn ich Backend-Aufrufe mache, dann mache ich das mit REST, mit Hypermedia-APIs” oder sowas. Oder “Wenn ich Frontend-Integration mache, dann mache ich das mit Links”, zum Beispiel. Kommen wir ja gleich noch zu. Das sind Sachen, die man offensichtlich irgendwie festlegen sollte, weil wenn das versucht, jeder anders zu machen, dann kann es effektiv nicht funktionieren. Es gibt irgendwie ein Set an Regeln, auf das muss ich mich einigen, sonst kann ich nicht integieren und wenn ich da eben fehlliege, wenn ich da die falsche Entscheidung getroffen habe, dann wird mich das üblicherweise auch deutlich mehr kosten, als wenn ich mich im Rahmen eines Projektes mal auf die falsche Frameworktechnologie festgeschossen habe.
Falk Hoppe: Ich glaube gerade bei SCS ist es halt sehr schwierig, weil wir ja eigentlich in ganz vielen Bereichen bei Self-contained Systems davon reden, dass wir eine Unabhängigkeit zwischen diesen Systems haben. Und diese Vertikalen-Unabhängigkeit sozusagen häufig damit verwechselt wird, dass jede Vertikale wirklich komplett das tun kann, oder soll, was sie will. Meistens ist es aber cleverer oder sinnvoller, in dieser Makroarchitektur halt eben die Infrastruktur sozusagen einmal durchzudeklinieren, wie diese SCSs halt eben zu integrieren sind. Deswegen finde ich das Wort Integrationsarchitektur da gar nicht so verkehrt, in dem Zusammenhang. Es ist halt da schon wichtig, dass man sich auf gemeinsame Vorgehensweisen einigt.
Eberhard Wolff: Das heißt also, wir würden jetzt in der Makroarchitektur oder Integrationsarchitektur die Dinge definieren, wie z.B. die Frontend-Integrations-Sachen, über die wir ja sprechen wollen, die wir ja übergreifend definieren müssen, weil wir sonst das System gar nicht zusammenbauen können, und dann würden wir wahrscheinlich weitgehend die anderen Entscheidungen freistellen und halt in der Mikroarchitektur pro System machen.
Heutzutage macht ja jeder moderne Webentwickler so Single-Page Apps mit Frameworks wie Angular, React oder so. Das höre ich auch im Zusammenhang mit Frontend-Integration. Erklärt mir kurz als Einstieg noch mal, was eigentlich Single-Page Apps genau sind.
Falk Hoppe: Ja, Single-Page Applications sind im Prinzip, würde ich behaupten, der klassische Rich Client, nur halt mit JavaScript implementiert. Das heißt, wir schieben eine Applikation zum Anwender hinüber, in der ganz viel Businesslogik enthalten ist und in der halt eben auch der State sozusagen vom Server an den Client übertragen wird. Und der Client vollumfänglich dafür verantwortlich ist, dem Nutzer die Applikation bereitzustellen. In klassischen Webanwendungen ist es eigentlich ja eher Server-getrieben, und bei SPA ist es dann eben rein Client-getrieben. In Zusammenhang mit der Frontend Integration macht man das halt erstmal häufig, weil man sagt, man schiebt sozusagen diesen SCS-Gedanken ein bisschen weiter weg, und hat in der Regel nicht mehr ein Frontend pro SCS, sondern hat ein gemeinsames Frontend, was halt ein SPA ist, und das halt im Prinzip nach hinten hin über Json-APIs dann klassischerweise die Integration vornimmt.
Till Schulte-Coerne: Aus der Architektursicht ist so eine Single-Page App häufig eben so eine Krake, die sich an irgendwelchen Backend-Services bedient, und eben die Integration sehr elegant machen kann. Also, es sieht immer schön aus, es hat halt irgendwie das Problem so ein bisschen, dass das natürlich eben gerade mit diesem Self-contained-Systems-Gedanken bricht, aber üblicherweise eben zu sehr großen Anwendungen dann führt.
Falk Hoppe: Es gibt schon auch Konzepte, wo man hingeht und sagt, man liefert einzelne Single-Page Applications aus und kommuniziert darüber, dass man Module miteinander teilt, indem man asynchron Module aus anderen Vertikalen lädt. Da hat man im Endeffekt den Split wieder auf eigene Frontends, aber man verliert die lose Kopplung, die man eigentlich gewonnen hatte, weil man sich auf eine Bibliothek einigt. Man muss dann klassischerweise sagen, wir gehen alle auf Angular 1, oder gehen alle in einem Schritt auf Angular 2, oder React und ähnliches.
Eberhard Wolff: Lasst uns nochmal zwei Schritte sozusagen zurückgehen. Also Single-Page Apps sind ja ein Ansatz, der zumindest relativ modern ist gerade, warum mache ich das überhaupt? Also warum baue ich Webanwendungen nicht so, wie ich es halt früher gemacht habe? Old school, mit HTML-Seiten, die halt einfach abgeschickt werden und wo halt eben dann irgendetwas passiert?
Falk Hoppe: Meiner Meinung nach ist die Hauptmotivation für Single-Page Applications – wenn man sie gut und und bewusst anwenden möchte – wenn man besonders aufwendige Frontends hat. Das heißt, wenn man ein Frontend hat, das aus vielen verschiedenen Komponenten besteht, die sich einen großen State teilen, und die viel miteinander kommunizieren. Da ist es relativ häufig sehr, sehr gut, wenn die Komponenten über den semantischen State Bescheid wissen, und dann auch häufig Logik mittransportieren können, um mit diesem State umzugehen. In solchen Umgebungen machen Single-Page Applications teilweise durchaus Sinn. Für diese Frontend-Integration sehe ich das an der Stelle halt eher zweifelhaft, weil das eigentlich nicht das Problem ist, was ein Single-Page Framework adressiert.
Eberhard Wolff: Aber also – wenn ich jetzt z.B. so eine Webseite bauen würde, wo ich halt irgendwie Sachen kaufen kann, klassische eCommerce Anwendung. Ist das etwas, was ich mit einer Single-Page App erschlagen würde?
Till Schulte-Coerne: Es ist halt eben sehr irreführend. Das ist auch das Problem, was ich mit diesem Begriff auch immer habe. Das heißt “Single-Page App”, das ist der Name dieser Grundanwendung. Das sagt aber überhaupt nichts über den eigentlichen Scope aus. Wenn ich einem Entwickler etwas davon sage, “Baue mir eine Anwendung”, dann übersetzt der Entwickler das natürlich damit, das hier ist gerade mein Scope, mein fachlicher Scope, mit dem ich gerade interagiere, mein Self-contained System, mein aktuelles Feature, was auch immer, und jetzt baue ich eine Anwendung, die genau das abdeckt, weil das ist ja eine Anwendung. Das heißt, ich betreibe sozusagen den Schnitt meiner Anwendung einfach da aus dem Kontext, in dem ich gerade in meinem Backend bin. Das ist aber gerade bei Single-Page Apps irgendwie etwas unschön. Dass du z.B. eben gesagt hast, ich habe einen Shop – wenn ich Single-Page Apps einsetze, dann muss ich das damit übersetzen, dass ich eine App habe, die die Funktionalität des Shops repräsentiert. Ich will dir da jetzt nichts unterstellen, aber das ist, glaube ich häufig, so, dass so was gesagt wird, das ist halt irgendwie ein Trugschluss. Aber das müsste gar nicht so sein. Das, was Falk beschrieben hat – auch wenn ich ein Single-Page-Skeptiker bin, zugegebenermaßen – das würde ich halt unterschreiben. Es gibt Dinge, da ist eine Single-Page-Technologie, sage ich jetzt mal, wirklich etwas Tolles, weil sie mir bestimmte Features bringt, sehr viel Engineering-Intelligenz vorhanden ist in diesen Frameworks, die mir sehr elegant bestimmte Problemstellungen im Web lösen. Aber das bedeutet nicht automatisch, dass ich auch alles so lösen muss. Sondern ich muss eben meine Funktionalität anschauen, und dann sehe ich halt, “Ok, ich habe hier eine komplexe, kollaborative Verarbeitung von Vertragsdaten, wenn jemand da was ändert, dann soll das jeder andere sehen, und überhaupt sollen irgendwelche Formularfelder dynamisch ein- und ausgeblendet werden, synchron bei 389 Sachbearbeitern, die alle vor derselben Maske stehen”, dann ist das vielleicht echt eine Supersache, wenn man diese Maske dann mit React meinetwegen macht. Aber das bedeutet nicht, dass ich alles andere, was in diesem System typischerweise auch noch drin ist, auch damit machen muss. Sondern mir geht es eben wirklich eher darum, dass man diese Single-Page-Technologien eben eher damit assoziert, dass man bestimmte Bestandteile einer Seite damit löst, und damit gehören sie halt aus meiner Sicht eben gerade nicht auf diese Integrationsebene.
Falk Hoppe: Also nehmen wir vielleicht mal dein Beispiel von der eCommerce Plattform. Wenn wir jetzt eine Seite haben, in der man z.B. ein Kleidungsstück kaufen kann. Und dann gibt es eine total tolle App dazu, die in der Seite eingebettet mir hilft, die entsprechende Größe auszurechnen, indem ich ein Foto hochladen kann und irgendwelche tollen Dinge einblenden kann. Und sich über Data Binding 15 Felder aktualisieren, automatisch meine Größe herausfinden, wie der Preis sich aktualisiert usw. Dann können das alles sehr, sehr sinnvolle Inhalte für eine Single-Page Application sein, der Scope wäre aber im Prinzip, dass das Ding eingebettet wäre auf einer Seite. Das muss nicht direkt das Integrationskonzept für die komplette Seite sein.
Eberhard Wolff: Das heißt wir diskutieren im Prinzip – die beiden wesentlichen Antworten aus meiner Sicht sind jetzt einmal ab einer bestimmten Komplexitätsklasse, würde ich Single-Page Apps benutzen, und gerade auch ab einer bestimmten Dynamik. Und die andere Ansage ist, dass wir eigentlich so eine Entscheidung eher auf Mikroarchitekturebene treffen wollen, pro Self-contained System, weil eben bestimmte Bereiche, bestimmte Fachlichkeiten vermutlich nur dieser Komplexitätsklasse angehören. So, damit sind wir wieder bei der anderen Geschichte – wenn ich jetzt sagen würde, ok ich baue eine Single-Page App, aus was für Gründen auch immer, und sage, das ist eben meine Lösung, mit der ich die gesamte UI bauen würde – ist das dann überhaupt ein Self-contained System? Weil die Aussage, die ihr ja gerade getroffen habt, ist, die Entscheidung für eine Single-Page App oder gegen eine Single-Page App wäre eine Mikroarchitekturentscheidung, die ich pro Modul treffen kann, wenn ich sagen würde, ich mache das global, wäre das eine Makroarchitekturentscheidung, und ich würde eben sagen, ok, wir machen das komplett mit Angular oder was weiß ich.
Till Schulte-Coerne: Es gibt Varianten, die in die Richtung zumindest gehen. Also, wenn ich ein Team habe, ein Team, was an irgendeinem anderen Standort sitzt, und das Angular App baut, die die gesamte Funktionalität aller meiner - wie soll ich sagen – Backend Self-contained Systems dann letzten Endes integriert, dann ist das natürlich kein Self-contained System. Das würde ich niemandem wirklich durchgehen lassen. Weil es halt eben eigentlich keine Chance gibt, das jemand was oben in dem Client ändert, ohne dass was im Backend geändert werden muss, und und und. Üblicherweise wird das einfach ein riesiger Monolith, das heißt, ich habe einen Frontend-Monolithen. Ich bin mal ein bisschen böse – es ist halt so ein Impuls: Frontend ist irgendwie, ja so ein bisschen schmuddelig. Ich habe supertolle Backends, tolle Leute im Backend, die tollen Code völlig entkoppelt von irgendwelchen anderen Leuten schreiben, und das ist alles total super, und ich deploye 15 Mal am Tag. Aber vorne, in meinem Frontend habe ich dann die alten Muster, die schon vorher immer so gut zum Erfolg geführt haben. Das ist offensichtlich irgendwie nicht so toll.
Was man machen kann: Es ist halt Code. Ja, JavaScript, auch wenn einige das nicht wahrhaben wollen, ist auch nur eine Programmiersprache, und die hat eben sogar, auch wenn einige das nicht glauben, ein Modularisierungskonzept. Die hat sowas sogar wie dynamisches Nachladen. Das, was dann eben manchmal sieht, ist, dass irgendjemand hingeht und sagt, “Hey wir benutzen Angular in der Version 1.x” oder React, oder was auch immer, wir benutzen das und laden dann verschiedene Bestandteile dieser Applikation dynamisch nach. Wir einigen uns sozusagen auf ein internes Angular-API. Ich beschreibe das in irgendeiner Form. Und dann habe ich halt z.B. Teams, die diese einzelnen Module dann entwickeln. Die dann eben zur Laufzeit zusammen gebaut werden. Das kann man diskutieren, ob das Self-contained Systems sind. Ich glaube, das kann man so nennen. Ich würde das trotzdem nicht empfehlen, weil ich nie irgendjemandem empfehlen würde, eine proprietäre Technologie, welche das auch immer ist, auf diese Makroebene zu heben. Auf der Mikroebene, proprietäre Technologien, geht ja gar nicht anders. Aber wenn ich über Integrationstechnologien rede, dann ist einer meiner wichtigsten Faktoren, dass ich möchte, dass ich auch irgendwann diese Entscheidung ändern kann. Und wenn man sich eben die Projekte anschaut, die klassischerweise sowas machen, ja, dann sieht man halt, dass die Änderung dieser Entscheidung normalerweise nicht mehr möglich ist.
Meine Frage ist immer, die Erste, wenn ich das sehe, ihr seid auf Frameworkversion 1.x, “Gibt es irgendeine Chance, dass ihr jemals auf Version 2.x kommt?”, und wenn die Leute dann ehrlich sind, dann sagen die meistens Nein. Weil das eben bedeuten würde, dass du alle Module zu einem Big Bang Zeitraum auf die nächste Frameworkversion hebst, und sie dann gemeinsam letzten Endes released, was halt eigentlich auch wieder einen monolithischen Charakter hat. Das ist ein bisschen spitzfindig, jetzt, den Leuten das abzusprechen, dass sie Self-contained Systems sind oder nicht – ich finde schon, dass das den Charakter hat, und die Idee finde ich grundsätzlich auch gar nicht so schlecht. Ich mag es halt einfach nicht, dass man sich von proprietären Dingen abhängig macht.
Falk Hoppe: Ich glaube, dass man Self-contained Systems an vielen Stellen weich definieren sollte, da reden wir z.B. auch über Kommunikation im Backend von API zu API, oder ähnlichen Geschichten. Ich glaube aber wirklich, dass man an der Stelle nicht mehr von Self-contained Systems reden darf. Bzw. Self-contained Systems sind eine Methodik, um Systeme zu entkoppeln, und in allen Bereichen, in denen sie definiert sind, lassen sie eigentlich nur asynchrone Kopplung zu. Und selbst wenn wir hier von asynchroner Kopplung zur Laufzeit reden, reden wir da immer von Code Injection. Das heißt, wir haben im Prinzip Systeme, die sich zur Laufzeit Code aus anderen Systemen holen, der ihren Code kaputtmachen kann. Das entspricht halt nicht den normalen Transklusionspattern, die man eigentlich in solchen Feldern vorfinden kann, da gehen wir vielleicht später auch noch drauf ein. An der Stelle ist es eigentlich genau eine Gegeninitiative zu Self- contained Systems. Deswegen würde ich an der Stelle immer sehr, sehr kritisch bleiben.
Eberhard Wolff: Das heißt, du sagst, es ist mehr als nur das Problem mit den Updates, sondern es ist ein allgemeineres Problem. Vielleicht sollten wir an der Stelle nochmal zwei Worte verlieren – also eigentlich ist das, was ihr sagt, dass sich die Frontends jetzt Code teilen, und dann eben über Modularisierungskonzept diesen Code nachladen würden. Wie sieht das denn aus, wenn ich jetzt sagen würde wir haben im Backend Code, und wir sagen, den Code im Backend teilen wir uns. Wie ist das denn da?
Falk Hoppe: Für mich ist das nur dann erlaubt, wenn es erlaubt ist, dass eine Vertikale in verschiedenen Versionen diesen Code anzieht. Nehmen wir mal an, in meinem Verständnis eines Self-contained Systems gibt es z.B. keine geteilte Datenbank. Das heißt, verschiedene Self-contained Systems können rein theoretisch in verschiedenen Datenbanken, Datenbankversionen betrieben werden. Das hieße, es könnte Bibliotheken geben, die diesen Treiber mitliefern. Dann darf der aber auch selbstverständlich in verschiedenen Versionen angezogen werden. Ohne dass das die Laufzeit der anderen Vertikalen betrifft.
Eberhard Wolff: Was ist denn mit – das ist ja jetzt technischer Code - was ist denn mit Geschäftscode und Geschäftslogik auf Codeebene, den im Backend zu teilen?
Falk Hoppe: Ich glaube, wenn man das nötig hat, dann hat man die Domäne falsch geschnitten. Also, wir reden eigentlich bei solchen Geschichten relativ schnell über Domain-driven Design, und von fachlichem Kontext. Wenn wir Kontext über solche Grenzen hinweg teilen, vergessen wir, glaube ich, relativ häufig, dass Informationen nur in dem Kontext Sinn machen, in dem sie spezifiziert wurden. Und wenn wir den über Grenzen hinweg teilen, koppeln wir uns entweder wieder sehr stark aneinander, oder wir vergessen halt eben, dass die Informationen noch einen anderen Mehrwert bieten in anderen Informationssystemen.
Eberhard Wolff: Genau. Und das war eigentlich das, worauf ich sozusagen hinaus wollte. Ich glaube, es gibt die Regel, nicht nur bei Self-contained Systems, sondern bei Microservices im Allgemeinen, dass eben Code Sharing etwas ist, was eigentlich herunterpriorisiert ist, und wo ja eben die Aussage ist, das führt - wie du ja richtig sagst – zu einer relativ starken Kopplung. Und eigentlich diskutieren wir jetzt, dass das im Frontend halt irgendwie ok ist. Weil die Wahrnehmung des Frontends anders ist, und das ist eigentlich bizarr. Das ist ja genau der Punkt.
Till Schulte-Coerne: Ja. Genau. Das sollte nicht so sein. Ich sehe das halt, wie gesagt, etwas liberaler als Falk, ich finde, das entspricht wenigstens in groben Eckpunkten der Ideologie von Self-contained Systems, wenn unterschiedliche Teams unterschiedliche Module liefern. Wenn sie auch ein Modul nachdeployen können, ohne alle anderen zu notifizieren, das kann man ja einfach mit Software Engineering Mitteln – Modularisierung auf Codeebene ist ja ein ganz altes Thema – man kann das gut und schlecht machen. Wenn man das gut macht, dann kann man sehr viele Grundideen von Self-contained Systems, glaube ich, auch korrekt übertragen, aus einer rein puristischen Sicht, ja aus einer formalen Sicht, müsste man es eigentlich ablehnen, weil eben letzten Endes die Entscheidung für ein bestimmtes Framework ein Bottleneck für die Zukunft sein wird. Was man eigentlich in dem Sinne nicht haben möchte.
Eberhard Wolff: Ja, und das, was mir dabei vor allem auch immer durch den Kopf geht, ist diese Sache, dass man im Backend sehr stark entkoppelt, und halt sagt “Code-Sharing ist halt nicht in Ordnung”. Und im Frontend –
Till Schulte-Coerne: Genau, warum sollte ich es im Frontend tun?
Eberhard Wolff: Genau. Und das ist halt inkonsistent.
Falk Hoppe: Das Problem ist auch, ich fände, es wäre eigentlich, also jetzt erstmal ideologisch wäre es schöner, wenn man das zur Buildzeit lösen könnte, und dann wären viele Dinge wieder rein theoretisch entkoppelt. Also, ich würde mir sozusagen die Frontend-Komponenten an einer anderen Vertikale holen, in der Version, in der ich die haben wollen würde. Das funktioniert aber gar nicht, weil halt eben diese API, oder eine SPA-API, die halt eben nicht nur aus den Komponenten und dem Verhalten besteht, sondern auch immer aus dieser Daten-API. Das heißt, wenn die Vertikale, von der ich diese Komponenten beziehe, intern ihre Daten geändert haben, funktionieren die Komponenten nicht mehr, die sie released haben. Das heißt, die müssen immer zur Laufzeit angezogen werden. An der Stelle. Wir können da nicht hingehen und sagen, wir gehen da mit dem SPA- Konzept hin und ziehen diese Komponenten-Integration in die Buildzeit.
Eberhard Wolff: Aber das wäre ja – jetzt eigentlich die Frage, die sich dann ergibt: Wenn du sagst, dass das zur Buildzeit de facto nicht möglich ist, warum hole ich mir da nicht die Komponenten zur Laufzeit, dann kriege ich sie halt jeweils in der aktuellen Version.
Falk Hoppe: Ja, aber dann haben wir halt eben dieses Problem, dass ich halt eben zur Laufzeit aktiven Code in meine Anwendung ziehe und dann halt eben Code- Sharing mache.
Till Schulte-Coerne: Wenn ich nicht damit interagiere, wenn ich das letzten Endes als isolierte Komponente eines Self-contained Systems ansehe, das wäre ja eigentlich die dritte Variante, die man dann hätte, dass man eben sagt, ích benutze Angular, um die Funktionalität meiner Vertikalen, keine Ahnung, so ein praktisches Beispiel ist leichter, irgendwie, die letzten Suchergebnisse oder sowas, oder die letzten Artikel, wenn ich dann eben einfach sage: Die Inhalte dieser Sachen oder dieser Vertikalen möchte ich mit einer Angular App, die von einem entsprechenden Team bereitgestellt wird, ausliefern, dann finde ich das völlig in Ordnung. Dann habe ich halt letzten Endes eine Komponente, auf einer anderen UI, in einem anderen Kontext, von dem ich überhaupt nichts weiß, aber die hat eben auch keine Code-Schnittstellen zu der Umgebung, sondern die wird halt einfach da initialisiert, wird dann irgendwie angezeigt, und ist eben auch wieder, in diesem Kontext, völlig self-contained. Weil ich eben nicht mit Code interagiere, der von einem anderen Team kommt, den ich einfach zur Laufzeit sozusagen dynamisch zusammenlinke, wenn man so will. Das finde ich halt auch nicht so gut.
Eberhard Wolff: Soweit zu Self-contained Systems, wie man Systeme zerschneiden kann, und wie man mit Single-Page Apps eine Integration erreichen kann. Im nächsten Teil werden wir uns um Alternativen zu Single-Page Apps kümmern, und darstellen, wie man konkret mit Self-contained Systems anfangen kann.