Webentwicklung mit TypeScript in Front- und Backend

3 Min. Lesezeit
Mittwoch, 22. Mai 2019

Single Language Web-App Prototyp in Docker

Üblicherweise arbeitet man in der Web-Entwicklung mit verschiedenen Technologien in Front- und Backend. Ein C# ASP.NET Backend, mit Anbindung an einen Microsoft SQL Server und einem Typescript Angular Frontend wäre ein typisches Beispiel. Prinzipiell hat sich diese Arbeitsweise auch bewährt. Ein Nachteil ist jedoch, dass man keinen Code zwischen dem Front- und Backend teilen kann. Insofern kommt es in manchen Bereichen, zum Beispiel beim Entity-Mapping oder bei der Validierung, zwingend zu Code-Verdopplung - und es gibt wenige Dinge die Entwickler mehr hassen als Code-Verdopplung.
Dieses Grundproblem hat mich auf die Idee gebracht, dass es doch durchaus möglich wäre, dieselbe Sprache im Front- und Backend zu verwenden. Nicht mit irgendeiner obskuren Sprache, sondern sogar mit jener, die Web-Entwickler ohnehin täglich verwenden: JavaScript beziehungsweise TypeScript.

Technologie

Gesagt getan. Um die Theorie zu prüfen, habe ich einen kleinen Prototyp gebaut, der folgendermaßen aufgebaut ist: Ein NodeJS Server mit ExpressJS und einer Sqlite Datenbank bilden das Backend. Das Frontend ist eine herkömmliche Angular Anwendung. Der gesamte Code ist somit in TypeScript verfasst. Die Anwendung ist noch dazu in einen Docker-Container verpackt. Warum? Nur weil Docker die heiße neue Technologie ist? Nein.
Das Verpacken hat den Vorteil, dass ein neuer Entwickler in diesem Projekt nur den Container herunterladen und zwei Batch-Skripts ausführen muss, damit das Projekt läuft. Man muss weder NodeJS, NPM, Angular, noch Typescript in Version XYZ installieren oder konfigurieren. Alles wird im Docker Container installiert, transpiliert und gestartet. Das spart Nerven und schont den Installations-Wildwuchs am Entwicklerrechner. Es laufen außerdem Watcher-Dienste, die den Server bei Änderungen sofort neustarten, damit man schnell und komfortabel entwickeln kann. Docker Container eignen sich auch ausgesprochen gut, um Deployments einfacher zu gestalten und zu automatisieren.

Funktionalität

Um die Vorteile der gemeinsamen Sprache zu demonstrieren, wurde eine Anwendung konzipiert, die möglichst einfaches Entity-Mapping erlaubt. Es gibt einfache Entitäten in der Datenbank, die im Frontend gelesen, angelegt, verändert und gelöscht werden können. Dabei soll der Entwickler nicht neben der eigentlichen Klasse auch noch DTOs, Klassen im Frontend und eine REST-Schnittstelle definieren müssen. Der Entwicklungsaufwand soll minimiert werden. Das wurde folgendermaßen umgesetzt:
Beim Starten des Servers werden alle registrierten Entitäten aus einem EntityCollection-Service gelesen. Aus jeder Entität werden deren Felder ausgelesen, es wird in der Datenbank eine Tabelle mit den entsprechenden Datentypen angelegt und es wird eine REST-Schnittstelle mit GET, POST, PATCH und DELETE Operationen geöffnet. (Hierbei sei angemerkt, dass Sicherheitsaspekte für diesen Prototyp bewusst außer Acht gelassen wurden. Dieser Mechanismus kann natürlich problematisch werden.) 
Die Angular Anwendung greift nun auf denselben EntityCollection-Service zu, liest ebenfalls das Objekt aus und generiert dynamisch eine Anzeigeliste, sowie ein Bearbeitungsformular für die neue Entität. Schlussendlich besteht das Anlegen einer neuen bearbeitbaren Entität dann nur aus zwei Schritten: Dem Definieren der Klasse und der Registrierung im EntityCollection-Service. Der Rest passiert vollautomatisch.

Conclusion

Der Prototyp zeigt, dass es möglich ist, ein und dieselbe Sprache im Front- und Backend einzusetzen. Durch die gemeinsame Codebase kann Aufwand eingespart werden, der sonst in überflüssige Doppel-Implementierung gesteckt werden müsste. Ob man diesen Technologie-Stack nun leichtfertig einsetzen will ist eine andere Frage. Es gibt viele prominente Nutzer von NodeJS, wie zum Beispiel Netflix, PayPal und LinkedIn. Kleine und mittlere Business-Anwendungen sind aber wahrscheinlich schneller und sicherer mit bewährten Technologien wie .NET oder Java entwickelt. TypeScript hat JavaScript zwar in Form von Typisierung die Zügel angelegt, dennoch erlaubt es Vieles, das in anderen Sprachen unmöglich wäre. Nichts hindert einen Entwickler, einen untypisierten String anzulegen und diesen mit 10 zu multiplizieren. Aus diesem und anderen Gründen sollte es gut überlegt sein, ob man TypeScript im Backend einsetzen will. Wenn aber das Projekt von den Vorteilen profitieren würde und das Team mit TypeScript kein Problem hat, dann könnte dieser Technologie-Stack durchaus produktiv genutzt werden.

Vorteile

  • Model-Klassen müssen nur einmal definiert werden, es werden keine DTOs benötigt.
  • Für eine einfache Entität muss keine neue REST-Schnittstelle definiert werden.
  • Entwickler können mit sehr geringem Installationsaufwand die Arbeit aufnehmen.
  • Durch die gemeinsame Technologie öffnen sich komplett neue Möglichkeiten. Zum Beispiel könnte man mit TypeScript und Sqlite eine offlinefähige Web-Anwendung bauen, die am Server und am Client dieselbe Datenbank und durch die gemeinsame Codebase auch denselben Daten-Layer-Code verwendet

Nachteile

  • Docker Konfigurationen sind schwieriger zu debuggen als die Konfiguration des eigenen Rechners.
  • Docker harmoniert nicht mit virtuellen Laufwerken die mit "subst" angelegt werden.
  • TypeScript ist weniger streng als C#. Dadurch kann die Code-Qualität sowie die Sicherheit leiden.
  • Je nach den genauen Anforderungen kann NodeJS + Sqlite für manche Aufgaben zu inperformant sein.