axelerator.de

Der fehlgeleitete Traum von Sprachmonogamie in der Webentwicklung

5 Minuten
#elm #rust
2 January 2024

In der sich ständig wandelnden Welt der Webentwicklung streben viele nach dem Ideal, die gleiche Programmiersprache sowohl im Frontend als auch im Backend zu verwenden. Wenn wir uns aber auf gemeinsame Daten anstatt auf eine gemeinsame Sprache Sprache konzentrieren, können wir das Beste aus beiden Welten rausholen ohne auf signifikante Synergien verzichten zu müssen. —

Content:


Der Traum von der einzigen Programmiersprache

Viele sind von der Idee angetan, eine einzige Programmiersprache für Frontend und Backend zu verwenden.
Node.js ist eine Laufzeitumgebung, mit der Entwickler JavaScript-Code serverseitig ausführen können.

Ein Grund dafür ist der Reiz, nur eine einzige Sprache beherrschen zu müssen. NodeJS beispielsweise bietet JavaScript-Entwicklern die Möglichkeit, ihr Backend in der gleichen Sprache zu schreiben, die der Browser versteht.


htmx ist eine Bibliothek, die es Ihnen ermöglicht, auf moderne Browserfunktionen direkt von HTML aus zuzugreifen, anstatt Javascript zu verwenden.

htmx bietet Backend-Entwicklern mehr Möglichkeiten, da sie nur HTML in ihrer Backend-Sprache schreiben müssen, um eine dynamische UX zu erstellen.

Ein zweites Argument ist die Idee, bestimmte Funktionalitäten nur einmal zu schreiben und sie sowohl im Front- als auch im Backend verwenden zu können. Halten wir jedoch inne und überlegen wir, ob diese Gründe ein vollständiges Bild ergeben oder lediglich eine Optimierung für ein lokales Maximum darstellen.

Entzauberung der Illusion

Meiner Meinung nach wird die Menge an Codes/Funktionalität, die tatsächlich zwischen dem Frontend und dem Backend geteilt werden kann, oft überschätzt wird. Das Backend und der Browser arbeiten in sehr unterschiedlichen Laufzeitumgebungen, die unterschiedliche Programmiermuster erfordern. Im Browser programmieren wir eine interaktive grafische Benutzeroberfläche. Im Backend ist die effiziente Verwaltung der Businessdaten unser primäres Ziel

Weiter würde ich behaupten, dass man in den meisten Fällen mindestens genauso viel (wenn nicht sogar mehr) Aufwand in das Erlernen des Frameworks (und des damit gelösten Problems) investieren muss wie in das Erlernen der Programmiersprache.

Zum Beispiel gibt es kaum Synergien zwischen dem Erlernen von, sagen wir, “React” und “Ruby on Rails”. Der Grund ist nicht so sehr, dass sie in unterschiedlichen Sprachen geschrieben sind, sonder die Tatsache, dass sie völlig unterschiedliche Probleme lösen.

Gemeinsame Datendefinition vs. gemeinsame Sprache

Das überwiegende Potenzial für Wiederverwendung von Code ist die Nutzung gemeinsamer Datenstrukturen!

GraphQL
ermöglicht es ein Schema für Datentypen und -beziehungen einer API definieren, das als Vertrag zwischen dem Client und dem Server dient und eine strukturierte und konsistente Kommunikation gewährleistet.

Um dies zu erreichen setzen viele Firmen GraphQL ein. Die Verwaltung einer “GraphQL-Schicht” ist jedoch mit erheblichen Kosten verbunden. Oft haben Unternehmen ganze Teams, die sich ausschließlich um die Integrität der GraphQL API kümmern. Darüber hinaus verfügt GraphQL über eine eigene (Schema-/Abfrage-)Sprache, die die Entwickler ebenfalls erlernen müssen.

Wenn man sich auf das richtige Problem - die gemeinsame Datendefinition - konzentriert und die Herausforderung, eine neue Sprache zu erlernen, ins richtige Verhältnis setzt, tun sich eine Menge interessanter Möglichkeiten auf.

Anstatt sich auf die Homogenität der Programmiersprache zu fixieren, bietet die Konzentration auf ein gemeinsames Verständnis von Datenstrukturen einen pragmatischeren und effektiveren Ansatz, um die Wiederverwendung von Code dort zu erreichen, wo es zählt.

Ein Praxisbeispiel: Das Zusammenspiel von Rust und Elm

Elm ist eine kleine Programmiersprache für die Front-End-Webentwicklung mit Fokus auf Einfachheit. In meinem vorherigen Blogpost schildere ich im Detail warum jeder Entwickler Elm ausprobieren sollte.

Elm ist eine funktionale Programmiersprache für die Front-End-Webentwicklung, die für ihr starkes Typensystem und ihren Fokus auf Einfachheit, Korrektheit und Zuverlässigkeit bei der Erstellung interaktiver Benutzeroberflächen bekannt ist.

Rust zeichnet sich im Backend durch seinen Fokus auf Sicherheit, Leistung und Gleichzeitigkeit aus und bietet eine robuste und effiziente Entwicklungserfahrung.

Die Wahl von Elm als Frontend-Sprache und Rust im Backend bietet uns das Beste aus beiden Welten. Da beide Sprachen statisch getypt sind, können wir die Typinformationen aus unseren Rust-Datenstrukturen verwenden, um automatiesiert Elm-Typen und (De-)Serialisierer zu erzeugen.

elm_rs ist eine Rust Crate die automatisch Typdefinitionen und Funktionen für Elm aus Rust-Backend-Typen generiert, so dass es einfach ist, die beiden auf dem gleichen Stand zu halten.

Das Backend ist die natürliche erste Wahl für die “Quelle der Wahrheit” wenn es um die Defintion der gemeinsamen Datentypen geht. Die elm_rs-Crate übersetzt diese Rust-Datentypen dann in die entsprechenden Elm-Typen (und De-/Serialisierer).

Anstatt die Komplexität der Anwengung durch eine dedizierte API-Schicht zu erhöhen, definieren wir zwei Datentypen ToBackend und ToFrontend, die jeweils die Nachrichten repräsentieren, die entweder zum Backend oder zum Frontend fließen. Diese Art der Kommunikation ist stark von Lamdera inspiriert.
Lamdera ist eine Full-Stack-Web-Plattform, die Elm sowohl im Frontend als auch im Backend verwendet. Allerdings kommt sie mit erhebliche Einschränkungen, wie sich Code im Backend ausführen lässt.

Auf diese Weise können wir Elm dafür einsetzen wofür es geschaffen wurde: Sicheres Arbeiten mit der Brwoser API ohne auf ansprchsvolle UI verzichten zu müssen. Im Gegenzug müssen wir uns im Backend überhaupt nicht mit HTML und dem Zustand der Benutzeroberfläche befassen.

Mein Startertemplate “Rülm” zeigt das so eine Architektur abseits von den populären Web-Frameworks nicht kompliziert sein muss. In weniger als 400 Zeilen Code bekommen wir eine Webanwendung die typsicher und effizient Daten in beide Richtungen austauschen kann. Und das alles ohne externe Build-Tools!