surech.ch – Homepage von Stefan Urech

Praktizierender Zyniker und Freidenker

NextCarWash: Die Architektur

| 1 Kommentar

Letzten Samstag habe ich meine neue Webseite NextCarWash zur Suche von Autowaschanlagen vorgestellt. In den nächsten paar Beiträgen möchte ich euch einen Blick hinter die Kulissen gewähren und auf einige technische Details eingehen.

Heute stelle ich euch die Architektur der ganzen Anwendung vor. Kurz: Wir haben es mit einer Single-Page-Anwendung zu tun, welche per REST mit einem JEEBackend kommuniziert.
Komponenten-Diagramm
Bitte entschuldigt die traurige Grafik, aber ausser Visio hatte ich gerade nichts schlaues zur Hand…

Backend
Das Backend ist mit JEE implementiert, was zwei Gründe hat:

  • In meiner Ausbildung hatte ich ursprünglich mal JEE vermittelt bekommen. Geschäftlich bauen wir unsere Anwendungen aber mit Spring. Mit diesem Projekt versuche ich das Schulwissen warm zu halten und so auf beiden Technologien fit zu bleiben.
  • Mit node.js habe ich schlicht zu wenig Erfahrung. Schon mit AngularJS habe ich mich im Frontend auf unbekanntes Territorium vorgewagt. Da wollte ich im Backend zumindest etwas vertrautes einsetzen. Wenn ich allerdings sehe, wie schnell man mit Node ein REST-Backend gebaut hat, habe ich manchmal schon gewisse Zweifel ab diesem Entscheid.

Die Daten werden in einer MySQL-DB gehalten. Dank den Spatial Funktionen kann man Koordinaten als nativer Datentyp ablegen und sowohl Umkreis- wie auch Bereichssuchen durchführen. Für den Zugriff auf die Datenbank verwende ich Hibernate, welches mit Hiberate Spatial auch schon das Rüstzeug für geografische Daten mitbringt. Einzig die Verwendung der Criteria API funktionierte nicht auf Anhieb, was ich aber mit einem eigenen Predicate lösen konnte.

Die JPA-Entitäten befinden sich in der Model-Komponente. Zwecks hoher Performance und tiefer Komplexität verzichte ich auf ein Mapping in DTO-Objekte. Statt dessen reiche ich die Entitäten direkt bis ins Frontend (oder in diesem Fall den REST-Service) durch.

Der Persistence- und Business-Layer wird jeweils durch eine Komponente abstrahiert, welche ausschliesslich die Interfaces der Services beinhaltet. Manch einer wird sagen, dass dies Over-Engineered sei und ich die einzelnen Implementation eh nie austauschen werden. Mir gefällt aber diese saubere Trennung, zumal der Aufwand für die Umsetzung relativ tief war.

Die Kommunikation mit der Aussenwelt geschieht über REST-Schnittstellen, implementiert mit JAX-RS. Die einzelnen Schnittstellen sind komplett stateless. Die serialisierbaren Klassen befinden sich in einer eigenen Komponenten und könnten somit auch von einem anderen Java-Client direkt verwendet werden. Mehr dazu in einem späteren Beitrag.

Frontend
Zu Beginn habe ich mir verschiedene Single-Page-Frameworks angeschaut und die entsprechenden Tutorials durchgearbeitet. Bei AngularJS gefiel mir sofort die clevere Bindung zwischen View und Model. Auch erhoffe ich mir, dass dem Framework mit Google im Rücken eine lange und sichere Zukunft bevorsteht. Zudem gibt eine wirklich ordentliche Dokumentation und eine gute Community, welche einem bei Fragen und Problemen unterstützt.
Die Karte wird mit Leaflet dargestellt, welches neben OpenStreetMap auch andere Anbieter wie etwas Google Maps unterstützt. Damit erreiche ich eine gewisse Unabhängigkeit von einem bestimmten Kartenanbieter.

Obwohl das Frontend nur reines HTML/CSS/JavaScript ist, befindet sich der Source in einer WAR-Komponenten. Damit kann ich die ganze Anwendung in einem grossen EAR deployen. Eventuell wird es zu einem späteren Zeitpunkt Sinn machen, das alles herauszulösen und mit einem performanten Webserver statt des (relativ) schwer-gewichtigen Wildfly auszuliefern.

Fazit
Die wichtigste Eigenschaft dieser Architektur ist, dass die ganze Client-Server-Kommunikation über die REST-Schnittstelle läuft. Der End-Benutzer erhält mit dem Single-Page-Ansatz eine sehr flüssige Oberfläche ohne Back-Reloads. Quasi geschenkt erhalte ich eine perfekte API, welche auch Dritte benutzen können. Perfekt deshalb, weil ich diese selbst für das Frontend verwende (Eat your own Dog food). Es gibt nichts schlimmeres als eine Schnittstelle, welche auf dem Reissbrett entsteht und von niemandem wirklich benutzt wird.
Mangels Status ist das Backend sehr gut skalierbar. Sollte die Seite viel Traffic generieren (was ich doch sehr hoffe!) kann ich einfach einen weiteren Server hinter einem Load-Balance hinzufügen. So erhalte ich eine nahezu lineare Skalierung bei minimalem technischem Aufwand.

Ein Kommentar

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.