Der Weg zur eigenen Web-App #2: Die Einrichtung

In diesem Beitrag zeige ich dir wie Du die Komponenten für eine moderne Web-App aufsetzt und damit entwickeln kannst.
Im ersten Beitrag der Serie erkläre ich die einzelnen Komponenten und deren Funktion.

Auf GitHub habe ich ein Repository für dieses Tutorial veröffentlicht. Die Datei ANLEITUNG.md leitet dich durch die einzelnen Schritte des Tutorials. Dieser Beitrag erklärt die einzelnen Schritte und den Quelltext der Anwendungen. Damit Du die einzelnen Schritte besser nachvollziehen kannst, habe ich für jeden Schritt einen eigenen git commit erstellt.
Im ersten Schritt installieren wir alle notwendigen Programme. Anschließend setzen wir die Projektstruktur sowie die Backend- und Frontendkomponente der Web-App auf. Nach dem ersten starten der Anwendung implementieren wir den Aufruf einer REST-Schnittstelle.

Schritt 0: Installation

In diesem Schritt installieren wir die einzelnen Programme. Folgende Programme werden benötigt:

  • Das JDK wird benötigt um Java Programme zu entwickeln und auszuführen
  • Maven ist ein Packetmanager und Build-Tool für Java. Mit Maven binden wir externe Bibliotheken ein und definieren einen Prozess zum Kompilieren der Anwendung.
  • NodeJS + NPM
    • NodeJS ist eine VM (virtuelle Maschine) für JavaScript, diese ermöglicht das Ausführen von JavaScript auf Servern. In unserem Fall ist der Angular Transpiler in JavaScript geschrieben.
    • NPM ist das equivalent zu Maven für JavaScript. Wir benötigen es um die Frontend Anwendung zu bauen und JavaScript Bibliotheken sowie das Angular Framework einzubinden.
  • MySQL wird für das Hosting einer Datenbank benötigt. Für Windows empfehle ich das Programm XAMPP, welches neben einer MySQL Datenbank auch einen Tomcat oder einen Apache Webserver beinhaltet.

Schritt 1: Projektstruktur Aufsetzen

Spring Boot

Das initiale Spring Boot Projekt erstellen wir über einen Generator von den Spring Entwicklern.
Unter dem Punkt “Projekt Metadata“ müssen eine sogenannte “Group” und ein sogenanntes “Artifact” eingeben. Die beiden Felder werden in der generierten pom.xml eingetragen.
Die Group ist der Name des Entwicklers oder des Projektes, dabei wird ein Domainname von hinten angegeben. Wenn ein Entwickler zum Beispiel die Domain “boot.springframework.org” besitzt, sollte dieser im Feld “org.springframework.boot” eingeben. In unserem Fall verwenden wir “demo.app” als Group.
Das Artifact ist der Name der Anwendung z.B. “spring-boot-starter”. Der Name sollte eine (Teil-)Anwendung in einem Projekt/System beschreiben. Wir verwenden “myfirst-app” als Namen für das Artifact.
Im Feld Dependencies werden alle benötigten Spring Bibliotheken eingegeben. Wir benötigen die Bibliotheken “web”, “jpa” und “mysql”.

  • Die Bibliothek web enthält allgemeine Funktionen für Web-Backends
  • Die jpa Dependency erleichtert den Datenbankzugriff über ein ORM-Mapping. Ein ORM-Mapping wandelt Datensätze aus SQL-Abfragen in Objekte um. Dies ermöglicht Datenbankabfragen, welche nach einzelnen Eigenschaften von Objekten filtern anstatt SQL zu schreiben.
  • Die mysql Bibliothek enthält einen Treiber für den Zugriff auf MySQL Datenbanken mittels Java

Die Datei “application.properties” enthält allgemeine Konfigurationseinstellungen und Spring erkennt diese Datei automatisch beim Start der Anwendung. In der Datei im Repository ist bisher nur die Datenbankverbindung konfiguriert.

Angular

Mit dem Befehl “npm install -g @angular/cli” installierst du ein Kommandozeilen-Tool zur Entwicklung von Angular Apps. Mit dem Tool generieren wir ein neues Projekt und später auch neue Komponenten. Das Tool bietet auch die Funktion die App auf dem lokalen PC bereitzustellen und für ein produktives Deployment zu bauen.
Um ein neues Projekt mit dem zuvor installierten Tool zu generieren wird der Befehl “ng new my-first-app” genutzt. Der Befehl “new” generiert ein neues Angular Projekt und “my-first-app” ist dabei der Name des Projektes.
Während der Ausführung werden zwei Fragen gestellt. In diesem Tutorial verwenden wir das Angular-Routing, daher bestätigen wir die erste Frage mit “ja” (also “y”).
Als “stylesheet format” verwenden wir “SCCS”. SCCS ist eine Erweiterung der herkömmlichen CSS syntax, mit welcher Variablen und geschachtelte Styles besser im Quelltext dargestellt werden können.
Im generierten Projekt sind folgende Dateien/Ordner wichtig:

  • src/
  • angular.json
  • package.json

Der Ordner “src” enthält den Quelltext. Die Datei “angular.json” konfiguriert das Angular Kommandozeilen-Tool. Die “package.json” enthält Verweise auf die externen Bibliotheken und beschreibt das Projekt. Die Datei bietet auch die Möglichkeit NodeJS Skripte zu definieren.
Mithilfe der Dateien “proxy.conf.json” und “angular.json” konfigurieren wir einen sogenannten reverse proxy. Im konkreten Fall bedeutet das sobald eine HTTP-Anfrage an den lokalen Frontend Server der Web-App gestellt wird, welche mit “/api” beginnt wird diese an den Backend Server weitergeleitet. Was genau der lokale Frontend Server ist erkläre ich unter Schritt 2. Die Datei “angular.json” enthält nur einen Verweis auf die “proxy.conf.json”.

Datenbank

Wir benötigen für unsere Web-App ein eigenes Schema. In der “application.properties” ist für die lokale Datenbank der Schema-Name “my-first-app” und der Benutzer “spring” mit dem Passwort “spring” konfiguriert.

Schritt 2: Der erste Start der Web-App

Die Backend Anwendung wird lokal durch die Ausführung der MyFirstApplication.java gestartet.
Die Frontend Anwendung wird über den Befehl “npm run start” oder “ng serve” ausgeführt.
Durch den Befehl wird die App transpilliert und über den lokal auf Port 4200 gehostet.

Schritt 3: Der erste REST-API Aufruf

Die Methode loadData in der Datei app.compontent.ts zeigt wie HTTP-Anfragen an das Backend gesendet werden. Dabei wird mit dem Keyword await asynchron auf die Antwort des Backends gewartet.

Die Klasse FooRestController zeigt, wie die REST-Schnittstelle bereitgestellt wird.
Dafür muss die Klasse mit der Annotation @RestController markiert werden. Die Annotation @RequestMapping an der Klasse ist optional, diese definiert den vorderen Teil der URL.
Die Methode getFoo stellt die letztendliche Schnittstelle bereit, diese muss mit der Annotation @RequestMapping markiert werden. Die Annotation an der Methode definiert den hinteren Teil der URL. Der Rückgabewert der Methode wird als JSON in der Antwort an den Client versendet:

{"username":"bar_username"}

JSON Daten vom Server

Die Antwort wird im Client dann ausgewertet und in diesem Fall wird der Benutzername in das Attribut username der Komponente geschrieben. Im HTML-Template wird gezeigt wie der Benutzername angezeigt werden kann. Dafür wird in den doppelt geschweiften Klammern der Name des Attributs geschrieben. Zuvor wird mit dem HTML-Attribut *ngIf geprüft ob der Benutzername gesetzt ist, wenn der Benutzername nicht gesetzt ist wird das HTML-Element nicht angezeigt.