Załóżmy, że szybko chcesz utworzyć pełnowartościową aplikację z backendem oraz frontendem. Ma w niej być dostępny mechanizm zarządzenia użytkownikami, czyli logowanie, zakładanie nowego konta, zmiana hasła itp. Fajnie jakby posiadała też internacjonalizację, metryki weryfikujące zużycie pamięci, listę dostępnych endpointów RESTowych, obsługę bazy danych… Dodatkowo wszystko powinno być pokryte testami jednostkowymi, integracyjnymi oraz end-to-end. Wisienką na torcie byłoby dodanie jeszcze CI/CD z wrzutką np. na Heroku. Sporo tego, ale to wszystko dostajemy wraz z użyciem projektu jHispter!

Czym jest jHipster?

Producenci określają ją jako platformę programistyczną do szybkiego generowania, rozwijania i wrzucania nowoczesnych aplikacji webowych oraz architektury mikroserwisowej. Frontend można oprzeć o Angluara, Reacta czy też Vue.js. Istnieje nawet możliwość tworzenia aplikacji mobilnych w Ionic bądź React Native. W backendzie do dyspozycji mamy Spring Boota wspieranego przez Javę albo Kotlina, Micronaut, Quarkus, Node.js czy też .Net. Wsparcie dla wgrywania aplikacji powstało dla AWS, Azure, Cloud Foundry, Google Cloud Platform, Heroku oraz OpenShift oczywiście opierając się o Dockera i Kubernetesa.

Jak z niego skorzystać?

Na starcie musimy zainstalować Javę, Gita oraz Node.js. Polecam oczywiście korzystać z najnowszej wersji Javy, aktualnie jest to wersja 16. Git jest niezbędny, aby jHipster za nas zainicjalizował repozytorium do wersjonowania kodu i wykonał pierwszego commita. Node.js pomoże nam zainstalować generator jHipstera wykorzystując polecenie npm install -g generator-jhipster.

Następnie należy utworzyć wybrany przez nas katalog, wejść do niego i po prostu napisać polecenie jhipster w konsoli. Zostaniemy przeprowadzeni przez bardzo prosty, składający się z kilku kroków generator.

Generator jHipster

Jeżeli wybraliśmy Mavena jako narzędzie do budowania projektu to wystarczy teraz wpisać polecenie ./mvnw i voila! Aplikacja powinna z powodzeniem odpalić się na porcie 8080.

Podstawowa aplikacja w jHipster

Po zalogowaniu mamy dostęp do wielu opcji. Możemy zarządzać użytkownikami, weryfikować metryki, sprawdzać status aplikacji, zmieniać konfigurację, przeglądać logi, używać API czy też wejść do bazy danych. Oczywiście możliwe jest przełączanie się pomiędzy językami wybranymi podczas generowania aplikacji. Dostępna jest również zakładka ‘Encje’, jednak na tą chwilę jest ona pusta. Jeżeli chcielibyśmy ją uzupełnić musimy skorzystać z JDL, czyli jHipster Domain Language.

Dostępne opcje w aplikacji jHipster

JDL, czyli jHipter Domain Language

W oparciu o tutorial znaleziony na YouTube stworzyłem własny plik z rozszerzeniem .jdl. Jego zawartość wygląda następująco.

entity Blog {
  name String required minlength(3)
  handle String required minlength(2)
}

entity Post {
  title String required
  content TextBlob required
  date Instant required
  status PostStatus required
}

enum PostStatus {
  DRAW, PUBLISHED, DELETED
}

entity Comment {
  author String required
  content TextBlob required
  date Instant required
}

relationship ManyToOne {
  Blog{user(login)} to User
  Post{blog(name)} to Blog
  Comment{post(title)} to Post
}

paginate Post with infinite-scroll
paginate Comment with pagination

JDL nie jest taki trudny jakby mogło się wydawać. Można w nim opisać wszystkie aplikacje, rury wdrożeniowe, encje i relacje pomiędzy nimi. Najlepiej wykorzystać do tego przyjazne dla oka studio w przeglądarce bądź też skorzystać z pluginów dla Eclipse czy VS Code.

Teraz musimy jakoś wgrać nasz plik do aplikacji, aby zadziała się magia. Dlatego kopiujemy nasz wygenerowany plik .jdl (w moim przypadku jest to blog-jdl.jdl) do katalogu z projektem. Następnie piszemy w konsoli polecenie jhipster jdl blog-jdl.jdl i czekamy na rezultat tych działań. Dostajemy informację, że wszystkie encje wygenerowały się prawidłowo.

Entity Blog generated successfully.
Entity Post generated successfully.
Entity Comment generated successfully.

Uruchommy ponownie aplikację wykorzystując jeszcze raz skrypt ./mvnw. Naszym oczom ukażą się napisane przez nas encje w zakładce ‘Encje’. W gratisie dostaliśmy testowe dane wygenerowane przy pomocy faker. Jeśli natomiast nie życzylibyśmy, aby tak się zadziało to dla profilu dev w pliku application-dev.yml usuwamy z spring.liquibase.contexts właśnie zmienną faker.

Wygenerowane encje przy pomocy JDL

Od kuchni programistycznej

Jeżeli otworzymy wygenerowany projekt w IDE to zobaczymy, że jest to nic innego jak zwykła architektura warstwowa. Mamy pakiety z repozytoriami, serwisami i kontrolerami. W pakiecie domain znajdują się stworzone przez nas encje. Podczas generowania zaznaczyliśmy opcję, aby przy autentyfikacji korzystać z JWT stąd pakiet security z niezbędnymi klasami do jego obsługi.

Struktura kodu jHipster

Utworzona została również adnotacja @IntegrationTest, którą oznaczamy klasy testowe do przetestowania ich integracyjnie. Pod tą adnotacją kryje się inna adnotacja @SpringBootTest uruchomiająca kontekst Springa podczas testowania. W ten sposób właśnie oznaczone są np. klasy UserServiceIT czy PublicUserResourceIT. Oczywiście istnieją też testy jednostkowe weryfikujące m.in. klasę UserMapper.

/**
 * Base composite annotation for integration tests.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SpringBootTest(classes = BlogApp.class)
public @interface IntegrationTest {
}

Wybraliśmy do testów end-to-end framework Cypress. Oczywiście za darmo dostaliśmy kilka takich testów, głównie dla panelu logowania. Wystarczy w konsoli napisać polecenie npm run e2e i patrzeć jak aplikacja jest testowana automatycznie. Jednak przed uruchomieniem testów musiałem wprowadzić małą modyfikację. W package.json usunąłem z linijki "e2e:cypress": "cypress run --browser chrome --record ${CYPRESS_ENABLE_RECORD:-false}" flagę --record, ponieważ musiałbym podać CYPRESS_RECORD_KEY do nagrywania testów czego na tą chwilę nie potrzebuję.

Nie zawarłem w tym artykule wrzucania aplikacji np. na Heroku. Jednak jest to przedstawione w oficjalnym filmie instruktażowym od jHipstera, którym inspirowałem się przy napisaniu tego tekstu.

Podsumowanie

jHipster wydaje się fajnym projektem, który w szybki sposób może pomóc nam w stworzeniu szkieletu aplikacji głównie w postaci CRUDa. Generator konsolowy oraz studio JDL w znaczy sposób upraszczają cały proces kreacji. Jednak na tą chwilę moja praca z jHipster ograniczyła się do oficjalnego tutoriala, więc nie wiem jakie problemy mogą zaskoczyć jego użytkowników. Podejrzewam, że skoro to jest tak ogromny projekt to nie raz może kogoś zaskoczyć jakiś niespodziewany błąd.