The Beauty of Clojure
Im Herbst 2018 sollte ein Prototyp für eine neue E-Beschaffung erstellt und auf dem traditionellen Wintertreffen der MACH AG im Dezember vorgestellt werden. Ziel war es, sowohl eine Designstudie zu schaffen wie auch bestimmte Entwicklungstechnologien zu erproben. Der Prototyp sollte aus einem Frontendservice bestehen, der das Web UI und die Businesslogik zur Verfügung stellt, und einem Backendservice, der für die Daten zuständig ist und über eine REST Schnittstelle eingebunden wird. Mein Part war es, den Backendservice zu implementieren. Da der Zeitrahmen, auch bedingt durch andere Verpflichtungen, sehr eng war, entschieden wir uns für eine Umsetzung mit Clojure. Der Backendservice war nicht Teil der Technikevaluierung.
Clojure ist eine JVM-basierte Programmiersprache, d. h. sie wird zu Java Bytecode compiliert und ähnelt damit konzeptionell Sprachen wie Scala oder Kotlin. Syntaktisch gehört sie zur Familie der Lisp Sprachen (d. h. "viele Klammern"). Im Gegensatz zu Java ist sie dynamisch typisiert. Clojure steht in der Tradition funktionaler Programmiersprachen, ohne die Strenge rein funktionaler Sprachen zu übernehmen. Über ihr historisches Vorbild Lisp hinaus bietet sie viele moderne Sprachkonzepte wie Immutable Values und Software-transactional Memory (STM). Natürlich ist eine gute Integration mit dem Java Ökosystem selbstverständlich.
All diese Eigenschaften machen Clojure zu einer idealen Sprache, um effizient zuverlässige Services zu entwicklen, doch keine davon war ausschlaggebend, sie für den anstehenden Prototypen zu benutzen. Aber ich hatte ähnliche Software kurz zuvor in Clojure erstellt, war mit den Libraries und den Tools gut vertraut und konnte mit der hohen Entwicklungsgeschwindigkeit rechnen, die ich von Clojure gewohnt war. Dieselbe Aufgabe unter den gleichen Randbedingungen mit Java anzugehen, hätte ich mir zu diesem Zeitpunkt wohl nicht zugetraut.
Da ein Clojure Service ohne Applikationsserver auskommen kann, war das Bootstrapping für den Service in kürzester Zeit erledigt. Ich benutzte das Template von Luminus, um die Projektstruktur zu erstellen und zugleich Support für Swagger anzulegen. Luminus legt auch das Build File an (project.clj), das – ähnlich wie bei Gradle – verschiedene Build Tasks zur Verfügung stellt, u. a. auch eine, um ein .war File zu erzeugen, das sich unter Wildfly deployen läßt. Ich entschied mich aber für den klassischen Ansatz, der ein self-contained .jar File baut, was man sofort auf einer Java Runtime deployen kann, und in dem alles Nötige enthalten ist, inklusive Web Server, Bibliotheken und Clojure Runtime.