jHipster im Einsatz

03.04.2019 | DaniD

„Don‘t repeat yourself“

Ein fundamentaler Grundsatz, der besonders in der Informatik gelebt wird. Bereits im Informatikstudium kommen Studierende mit diesem Paradigma als Bestandteil von „Clean Code“ in Programmiervorlesungen in BerĂŒhrung.

In erster Instanz geht es hierbei darum, wiederkehrende Aufgaben in dedizierte Programmblöcke auszulagern und dann bei Bedarf aufzurufen – Stichwort Methoden und Funktionen. Schnell wird man aber erkennen, dass sich dieses Grundprinzip in weiteren Bereichen der Softwareentwicklung anwenden lassen sollte. Bestimmte TĂ€tigkeiten wiederholen sich bei jedem neuen Software-Projektsetup. Dazu zĂ€hlen beispielsweise das Einrichten eines Code-Repositorys, Erstellen einer Deployment-Pipeline und nicht zuletzt das Aufsetzen von Skeletons fĂŒr Clients und Backend. Um einige dieser essentiellen Setupschritte nicht bei jedem neuen Projekt von Grund auf durchfĂŒhren zu mĂŒssen, gibt es diverse Lösungsvarianten. PopulĂ€r sind aktuell Coderepositories, die fĂŒr viele Plattformen und Technologien vorkonfigurierten Boilerplate-Code bereitstellen, um einen schnellen Start mit den wertgenerierenden Aufgaben zu ermöglichen.

Nebst solchen Repositories haben sich auch eine Reihe von Code-Generatoren entwickelt, die repetitive Aufgaben abnehmen sollen. Oft wird bei der Verwendung dieser Generatoren zunĂ€chst ein Reihe von Fragen bezĂŒglich der zu erstellenden Anwendung gestellt. Ja nach Antwort werden unterschiedliche Aspekte der neuen Applikation hinzugefĂŒgt oder weggelassen.

Eine populÀre Konstellation im Webumfeld ist ein Spring Boot -Backend inklusive Datenbankanbindung, das via ReST-Schnittstellen mit einem WebClient, zum Beispiel Angular oder VueJS, kommuniziert. Eine Lösung die diese Zusammenstellung adressiert ist jHipster. Der FullStack-Generator wurde 2013 ins Leben gerufen und wird seither stetig weiterentwickelt und angepasst.

Die Erstellung einer jHipster-generierten Anwendung gestaltet sich als sehr unkompliziert. Dabei existieren mehrere Wege, um zur initialen Version zu kommen. Es besteht die Möglichkeit den jHipster-Generator als lokale Komponente zu installieren. Diese lĂ€sst sich ĂŒber das Terminal beziehungsweise Kommandozeile bedienen. Nach dem Start des Generators wird anhand eines Fragenkatalog die gewĂŒnschte Konfiguration ermittelt. Die daraufhin erstellte Anwendung ist in der Regel sofort startbereit. Daneben besteht die Möglichkeit, den gleichen Fragenkatalog online auszufĂŒllen und die Applikation komplett als ZIP-Archiv herunterzuladen. Daneben gibt es diverse andere Möglichkeiten fĂŒr das initiale Projekt, wie als Docker Image und ĂŒber diverse Packagemanager.

Im Rahmen einer Evaluation, welche Möglichkeiten sich zu schnellen Erstellung einer Applikationsgrundstruktur im Webumfeld eignen, haben wir uns jHipster genauer angesehen. Gewisse Punkte sind uns dabei aufgefallen. Meist positive, aber auch einige, mit denen wir etwas zu kĂ€mpfen hatten. Je nach Einsatz kann dies fĂŒr den ein oder anderen aber weniger eine HĂŒrde darstellen.

Wir haben uns hierfĂŒr fĂŒr eine monolithische Anwendung mit Angular in der Version 6 entschieden.

Installation

Insgesamt haben wir es als sehr positiv empfunden, dass mehrere Wege zum jHipster-Skeleton angeboten werden. Über den lokal installierten Generator, als ZIP-Archiv ĂŒber jHipster-Online oder Paketmanager.

Die lokale Installation des jHipster-Generator gestaltet sich teils etwas mĂŒhsam. Wir haben unsere Gehversuche mit jHipster auf einem frisch aufgesetzten MacBook unternommen. Um jHipster installieren zu können, musste zunĂ€chst homebrew und dann yarn installiert werden. Auf einer altgedienten Entwicklermaschine dĂŒrften diese Dependency-Manager in der Regel aber schon vorhanden sein, womit dieser Punkt nicht so sehr ins Gewicht fĂ€llt.

N:M-Beziehungen

In der getesteten Version (5.8.1) beherrscht jHipster leider das Erzeugen von n:m-Beziehungen noch nicht. Diese Option steht weder beim Erzeugen der EntitĂ€ten mithilfe des Generators noch im erzeugten WebClient zur VerfĂŒgung. Blog- und StackOverflow-EintrĂ€ge lassen aber darauf schliessen, dass an diesem Feature gearbeitet wird.

Um n:m-Beziehungen dennoch zu realisieren, bleibt daher aktuell nur der manuelle Eingriff. Dabei gilt es die EntitĂ€tsklasse mit einer entsprechenden JPA-Annotation zu versehen. Ausserdem muss das dazugehörige DTO und der entsprechende Mapper ergĂ€nzt werden. Auf Clientseite kann diese Art der Beziehung unterschiedlich abgebildet werden. Eine einfache Lösung ist die Verwendung eines Select-Elements, das eine Mehrfachauswahl unterstĂŒtzt.

EntitÀten

Wie eingangs erwĂ€hnt, wiederholen sich gewisse Aufgaben mit den Wachstum der Anwendung. Zum Beispiel werden mit dem HinzufĂŒgen einer EntitĂ€t in der Regel auch neue DTOs und Mapper zwischen DTO und EntitĂ€tenklasse geschrieben. Dies zieht normalerweise auch ein Datenbank-Update nach sich. Dies alles geschieht oft nach dem immergleichen Schema. Auf Clientseite gestaltet sich das gleiche Szenario.

Um dem Entwickler von diesen monotonen Prozessen weitestgehend zu entlasten, generiert jHipster alle notwendigen Bestandteile vom Backend bis zum Client. Ähnlich dem initialen Erstellen des Skeletons fĂŒhrt ein terminalbasierter Fragenkatalog durch den Generierungsprozess. Das Ergebnis ist eine JPA-annotierte Entity inklusive möglicher Constraints, ein DTO, eine Model-Mapperklasse und die Datenbankmigrationsbeschreibung via Liquibase. Auf Clientseite generiert jHipster eine eigene Komponente fĂŒr die EntitĂ€t, die das Template, Controller, Modell sowie Tests enthĂ€lt.

Da EntitĂ€ten auch nachtrĂ€glich via jHipster um Attribute ergĂ€nzt oder von diesen erleichtert werden können, wird clientseitig die betroffene EntitĂ€t komplett neu generiert. Eventuell gemachte Änderungen an dieser EntitĂ€t werden ĂŒberschrieben. FĂŒr unseren Testfall hat es sich als Best Practise erwiesen, Komponenten, die nicht ĂŒber jHipster generiert werden sollen, weil sie beispielsweise keiner EntitĂ€t entsprechen oder nur anzeigenden Charakter haben, nicht in der logisch zugehörigen Komponente abzulegen. Stattdessen fĂŒhrten wir ein custom-Modul ein, in dem ebendiese Komponenten organisiert und registriert sind.

Fazit

jHipster leistet sehr gute Arbeit fĂŒr weit verbreitete Arten von Applikationen. Applikationen nĂ€mlich, die ihre Informationen in EntitĂ€ten ablegen und nach dem CRUD-Prinzip verwalten. Ja nach Architekturansatz sind diese Bedingungen fĂŒr viele Anwendungen zutreffend. FĂŒr Webapplikationen mit statischem Inhalt ist eine vollstĂ€ndige jHipster-Anwendung aber zu schwergewichtig. Die StĂ€rke von jHipster liegt also unter anderem auch darin, dem Entwickler so viel repetitive Arbeit wie möglich abzunehmen. Besonders bei der Generierung der ĂŒblichen CRUD-Methoden sowohl auf Client- als auch auf Serverseite macht sich dies deutlich bemerkbar.

Unserer EinschĂ€tzung und der entwickelten Applikation nach eignet sich der generierte Code durchaus auch fĂŒr den produktiven Einsatz. Auch wenn jHipster besonders im Umfeld des “Rapid Prototypings” sich einen Namen gemacht hat. Viele Sicherheitsaspekte und Best Practises werden vom jHipster-Generator adressiert und angewandt. SelbstverstĂ€ndlich muss die erzeugte Anwendung aber noch an das jeweilige Produktionsumfeld angepasst werden, da der Fokus zunĂ€chst auf einer direkt lauffĂ€higen und schnell erweiterbaren Applikation liegt, die das Entwicklungsteam möglichst rasch um wertvolle Businesscases ergĂ€nzen kann. Besonders in Bezug auf den erzeugten Webclient soll noch darauf hingewiesen werden, dass dieser lediglich ein Administrationswerkzeug fĂŒr die zu verwaltenden EntitĂ€ten darstellt. Einen spezialisierten Client zu entwickeln, der die BedĂŒrfnisse des Endbenutzers erfĂŒllt, ist in der Regel die Aufgabe des Entwicklungsteams. Im besten Fall kann allerdings der Output des Generators fĂŒr die AdministrationsoberflĂ€che auch fĂŒr den Endbenutzer-Client verwendet werden.