Jhipster

Jhipster is een volledige stack om webapplicaties te genereren en te bouwen. De belangrijkste frameworks waar Jhipster gebruik van maakt, zijn Spring voor de backend en Angular/bootstrap voor de frontend. Jhipster gaat sinds versie 3 zelfs nog verder, zodat je Jhipster kunt gebruiken om een microservice architectuur op te zetten. Ben je van plan om een webapplicatie te bouwen met deze drie technologieën, dan is Jhipster de moeite waard om uit te proberen. Je kunt veel boilerplate code laten genereren, zodat jij je volledig kan storten op het bouwen van functionaliteit. Dit geldt vooral voor projecten waarbij je gebruik wilt maken van zowel frontend als backend build tooling.

Daarnaast zijn voor de gegenereerde code zowel frontend, backend en performance testen gegenereerd die je eenvoudig kunt uitbreiden met testen voor de code die je toevoegt. Voor de dataopslag kun je verschillende relationele databases gebruiken of noSQL technologieën, zoals Cassandra en Mongodb. Er is zelfs gedacht aan Elastic Search als je tekstueel zoeken in de database wilt ondersteunen. De volledige technologie stack kun je terugvinden op http://jhipster.github.io/tech-stack/. Een Jhipster applicatie is zowel standalone te draaien alsmede als een standaard war te deployen op een applicatie server. Ook is er ondersteuning om Docker files te genereren, zodat je de applicatie direct in Docker containers kunt draaien.

In dit artikel maken we kennis met Jhipster. We beginnen met het installeren en als voorbeeld gaan we een simpele monolithische webapplicatie opzetten om de basis van Jhipster door te krijgen. Hierna beschrijf ik de mogelijkheden die Jhipster biedt om een microservice architectuur op te zetten inclusief service discovery en centrale monitoring. De gebruikte source in dit artikel kun je vinden op Gitlab (https://gitlab.com/benoomsdh/jhipstersample.git).

Zoals aangegeven in de introductie maakt Jhipster voor de backend gebruik van Spring Boot. Voor de frontend wordt gebruik gemaakt van HTML5 boilerplate als template, Bootstrap voor CSS en AngularJS voor de integratie. Dit gaat ervan uit dat je jouw applicatie als Single Page App (SPA) wilt opzetten. Mocht je dit niet willen, dan is er ook support voor Thymeleaf templating. In dit artikel gaan we uit van een SPA zonder gebruik te maken van Thymeleaf.

Een snelle manier om een complete ontwikkelomgeving voor Jhipster op te zetten, is door gebruik te maken van Vagrant. Hiervoor moet je wel Vagrant en Virtualbox installeren. Jhipster levert een ontwikkelbox met alle tooling die nodig is om Jhipster applicaties te ontwikkelen. Dit is aan te raden wanneer je niet de benodigde tooling hebt en snel aan de slag wilt met Jhipster. Nadat je de commando's "vagrant init jhipster/jhipster-devbox" en "vagrant up –provider virtualbox" uitgevoerd hebt, heb je een Ubuntu gebaseerde virtuele machine waarin je kunt ontwikkelen. Mocht je hier ook gebruik van maken, vergeet dan niet om in de Vagrant configuratie file in ieder geval de hoeveelheid RAM te vergroten. Rond de 3GB is voldoende om ook de Eclipse IDE binnen de virtuele machine te gebruiken.

Voor het genereren van de applicatie wordt gebruik gemaakt van een JavaScript generator, genaamd Yeoman. Via de commandline worden een aantal vragen gesteld om de juiste basis te genereren. Maak een directory aan met de naam “blogapp” en navigeer naar de gemaakte directory. In de command prompt tik je het commando "yo jhipster". Voor dit artikel zijn de gemaakte keuzes in afbeelding 1 te zien.

afbeelding 1

Uit de gestelde vragen kun je afleiden wat de mogelijkheden van Jhipster zijn. Voor dit artikel heb ik ervoor gekozen om het zo simpel mogelijk te houden. Nadat de generator zijn werk heeft gedaan, hebben we een complete Maven en Gulp gebaseerde applicatie. Hierbij zijn ook verschillende Maven profielen voor zowel development als productie. Je hebt nu een volwaardig applicatie framework draaien die gereed is om de gewenste functionaliteit in te bouwen.

Om de applicatie te starten, kun je mvn aanroepen die de default task "spring-boot:run" zal uitvoeren. De applicatie is dan te benaderen via http://localhost:8080. Standaard wordt het dev profiel gebruikt en de Spring boot tools actief, wat betekent dat je backend bij wijzigingen opnieuw geladen wordt. Omdat we ook een volledige frontend build omgeving hebben, kunnen we in een andere terminal het commando "gulp" uitvoeren. De standard Gulp taak die dan uitgevoerd wordt, is "browsersync". De frontend applicatie is dan beschikbaar onder "http://localhost:9000". Bij alle frontend wijzigingen wordt de browser automatisch ververst, zodat je meteen het resultaat kan zien. Dit alles met een volledige connectie naar de backend, dus zonder gebruik te maken van stubs. De frontend maakt dan gebruik van de api die op poort 8080 beschikbaar zijn.

We hebben nu een applicatie gegenereerd met een AngularJS frontend en een Spring Boot backend. Standard inbegrepen zijn Dropwizzard metrics, REST documentatie d.m.v. Swagger, User Management, runtime aanpasbare logging levels, versiebeheer van de database door middel van Liquibase en een web tool om de database te benaderen. Al deze tools zijn te vinden in het menu "Administration", nadat je ingelogd hebt als admin. Niet gek toch voor het uitvoeren van een commando? Daarnaast zijn er backend en frontend testen genereerd. Ik adviseer om, voordat je verder gaat, de testen uit te voeren. Dit kun je doen met de commando’s "mvn test" en "gulp test". De reden hiervoor is dat de generatie weleens kan mislukken, het gaat dan mis met de frontend dependencies. Dit is zichtbaar bij het draaien van de gulp testen.  

Voordat we verder gaan, is het ook handig dat je versiebeheer toepast en de gegenereerde applicatie commit. Bij de generatie van de applicatie is ook een .gitignore bestand aangemaakt, waardoor je na een git init meteen een commit kan doen zonder onnodige bestanden in versiebeheer te zetten.

Laten we beginnen met het implementeren van onze blog. Het model is simpel gehouden. Onze gebruikers kunnen na registratie artikelen aanmaken. Een artikel heeft een titel, inhoud, auteur en aanmaakdatum. Daarnaast kan een artikel nul of meerdere tags hebben. Artikelen kunnen alleen door de auteur en site admin gewijzigd worden. Alle gepubliceerde artikelen worden als lijst getoond op het beginscherm.

Om het model te implementeren, zijn er verschillende opties, van de command line tot grafische tooling. Een voorbeeld van ons model zie je op afbeelding 2.

 afbeelding 2

We gaan voor dit voorbeeld de commandline entity-subgenerator gebruiken. Om een entiteit te creëren, gebruiken we het commando "yo jhipster:entity <entiteitnaam>". Goed om te weten, is dat de entiteit naam gebruikt wordt als Java klasse naam, dus voor onze ‘artikel’- entiteit gebruiken we Article als naam. Dit zal resulteren in een Java klasse Article en een tabelnaam article in de database. Bij het aanmaken van een entiteit heb je de mogelijkheid om validatie regels mee te geven, die gebruiken wij dan ook. Vanuit de ‘artikel’- entiteit willen we een relatie naar de ‘gebruiker’-entiteit hebben. Deze relatie kunnen met een "manyToOne" linken aan de User. De User hebben we niet zelf gedefinieerd, maar dit is de entiteit die voor Spring Security is aangemaakt. De enige beperking bij het gebruiken van de User is dat we geen attributen aan de User toe kunnen voegen. Er kan dus alleen naar de User gelinkt worden. De relatie gebruikt standaard het id veld en je krijgt de mogelijkheid om voor de frontend een ander veld voor de view te gebruiken, in het voorbeeld gebruik we het login veld. Doen we dit niet, dan zou je als auteur van een artikel het id zien en geen naam.

Zoals je in de console kan zien, is er veel gebeurd. Er is in de backend een Liquibase changeset aangemaakt, een Java entiteit met JSR 310 Bean validatie en een Spring Data repository. Voor de frontend zijn AngularJS services, controllers en diverse views inclusief front-end validatie gegenereerd.

Daarnaast zijn er ook testen gegenereerd voor de backend, front-end en performance testen. Als je bekend bent met de gebruikte frameworks, dan zijn de gegenereerde bestanden gesneden koek. Eén bestand wil ik wel toelichten, omdat deze Jhipster specifiek is. In de directory “. jhipster" is het bestand Article.json aangemaakt. Voor elke entiteit die je aanmaakt, wordt een json bestand aangemaakt. In het json bestand is de entiteit beschreven. Jhipster gebruikt dit om de entiteiten te genereren. Je kunt ook het Json bestand zelf veranderen en de entiteit opnieuw genereren.

Als je de applicatie start en inlogt, dan zal je nu in het entiteit menu de Article entry vinden. We kunnen nu artikelen aanmaken en tonen. De volgende stap is het aanmaken van tags. Hiervoor maken we een Tag entiteit aan met als attribuut een naam die uiteraard verplicht is. Als relatie maken we een many to many relatie aan met Article, waarbij de ‘Article’-entiteit de eigenaar is van de relatie.

We zijn bijna klaar met ons model. Als je nu de testen uitvoert (mvn test, gulp test), dan zal je zien dat deze falen doordat het attribuut "tags" niet gevonden wordt in "Article". Dit klopt ook, we kunnen met de generator de Article entiteit gaan verrijken met de many to many relatie met het Tag object die we de naam tags geven (het wordt immers een set van tags).

Het model voor onze blog is nu af, we kunnen spelen met de CRUD schermen om vast te stellen dat ons model goed is. In de views worden de velden gebruikt die we tijdens de generatie hebben opgegeven.

We kunnen nu de applicatie gaan tweaken om aan onze eisen te voldoen. Laten we bij de backend beginnen. Alle calls naar de REST API kunnen alleen door geauthentiseerde gebruikers gedaan worden. Om de artikelen te kunnen tonen, moeten we eerst zorgen dat de backend alle GET-requests naar de artikelen API voor alle gebruikers mogelijk maakt. De security configuratie is vastgelegd in de klasse "SecurityConfiguration". In de methode "configure" wordt een Spring Security HttpConfiguration object opgebouwd. Voeg bovenaan de ANT matchers die in het authorizeRequest deel staan de volgende regel toe:


 ".antMatchers(HttpMethod.GET, "/api/articles/**").permitAll()".

Nu kun je zonder in te loggen artikelen ophalen. Voor de eis dat alleen de auteur of de admin artikelen mogen wijzigen, moet ook de security configuratie worden aangepast. In de huidige toestand kunnen alle gebruikers artikelen aanmaken, wijzigen en zelfs verwijderen. Het makkelijkste is om dit in de ArticleResource klasse te doen. We kunnen gebruik maken van de SecurityUtils klasse die door Jhipster gegenereerd is. Met een helper methode kunnen we vaststellen of een ingelogde gebruiker admin of auteur van een artikel is en kunnen wij deze gebruiken om vast te stellen of de actie mag worden uitgevoerd, zie afbeelding 3.

afbeelding 3

Daarna kunnen de methodes voor het opslaan, wijzigen en verwijderen hiervan gebruik maken. Nu hebben we een backend die aan onze eisen voldoet en kunnen we de gegenereerde frontend gebruiken om vast te stellen dat je alleen als auteur of admin artikelen kunt wijzigen en verwijderen. Nu laat ik de frontend wijzigingen aan de lezer om te implementeren, maar ook hiervoor hoef je weinig te doen. Je heb een AngularJS service tot je beschikking voor de artikelen en met de gegenereerde code als voorbeeld ben je zelfs zonder een frontend whizzkid te zijn snel klaar. In de repository is de frontend code ook aangepast, zodat je kunt zien hoe het zou kunnen.

Ik hoop dat je door dit kleine voorbeeld een beeld hebt gekregen hoe gemakkelijk het is om met Jhipster aan de slag te gaan. Naast tools voor het snel bouwen van prototypes is er veel ingebouwd in Jhipster waardoor een applicatie snel productiewaardig is te maken. Naast de functionaliteit om een monolithische applicatie te genereren is het sinds Jhipster versie drie ook mogelijk om een microservice architectuur op te zetten.

Zoals je ziet, is er veel mogelijk met Jhipster. De bedoeling van dit artikel is om als appetizer voor Jhipster te dienen of je nou wilt spelen met technologieën, snel een applicatie wilt maken of een complete microservice architectuur wilt opzetten. Ik heb in dit artikel maar een fractie van de mogelijkheden besproken, de documentatie van Jhipster is erg goed en daar zal je nog veel meer mogelijkheden ontdekken.

Wat Jhipster laat zien, is dat als je een aantal bewezen frameworks combineert je flink wat boilerplate kunt genereren en jij je als ontwikkelaar volledig kunt focussen op de functionaliteit die je wilt bieden. Hierdoor kun je snel en relatief eenvoudig serieuze applicaties bouwen. Goede bronnen zijn de Jhipster pagina (http://jhipster.github.io) en een aantal bronnen van Matt Raible (http://raibledesigns.com) waaronder een mini boek genaamd "The Jhipster mini-Book". Aanraders zijn ook een aantal presentaties die hij gegeven heeft op verschillende Devoxx meetings en als webcast te zien zijn.