Vorteile von Nest.js bei der Node.js Backend-Entwicklung

Montag, 17.7.2023

Titelbild Node.js Backend

 

Traditionell wird bei der Backend-Entwicklung mit Node.js eine Library wie Express eingesetzt. Express verfügt auf npm über fast 30 Millionen Downloads in der Woche und ist damit einer der populärsten Node.js-Webserver.

Express vereinfacht den Bau von REST-APIs im Vergleich zu den Standard-APIs von Node.js deutlich. Insbesondere die vielen Middlewares, also Erweiterungspakete, mit denen sich neue Funktionalität zu Express hinzufügen lässt, sind sehr hilfreich.

Mit dem Express-Router kann einer Codebasis mehr Struktur gegeben werden, indem etwa alle Routen zu einer Ressource in eine Datei ausgelagert werden können:

Auch wenn der Express-Router hilft, eine gewisse Struktur in der Codebasis zu etablieren, so würde ich mir doch noch mehr Patterns wie in der Java-Welt wünschen: Beispielsweise lassen sich mit dem Spring Framework Beans, Services, Controller und vieles mehr definieren. Diese Patterns helfen, eine Codebasis zu strukturieren.

Ähnliche Konzepte gibt es auch im Frontend-Framework Angular, welches klar zwischen Services und Komponenten unterscheidet und wo Abhängigkeiten per Dependency Injection bereitgestellt werden können.

Nest.js

Nest.js ist ein Open-Source-Projekt, welches Backend-Entwicklung mit Node.js ermöglicht und die oben gewünschten Features bietet. Nest.js basiert auf Express, es kann aber auch mit Fastify, welches besonders schnell HTTP-Anfragen beantworten kann, genutzt werden.

Im Folgenden gehe ich auf einige Features von Nest.js ein, die dieses Framework für mich zu einer interessanten Wahl für die Backend-Entwicklung mit Node.js machen.

Statische Typisierung mit TypeScript

Das Framework nutzt TypeScript, d. h. Nest.js-Projekte sind statisch typisiert. Dies ist insbesondere für Enterprise-Applikationen ein großer Vorteil, da die statische Typisierung hilft, Fehler zu vermeiden. Durch die Unterstützung der Entwicklungsumgebung funktionieren außerdem Features wie etwa Autovervollständigung oder Code-Refactorings deutlich besser.

Dependency Injection

Die statische Typisierung ist aber quasi noch Wegbereiter für ein anderes Feature von Nest.js: Dependency Injection. Per Dependency Injection können sogenannte Provider, also etwa Services oder Repositories injiziert werden, d. h. wenn diese Provider benötigt werden, werden sie automatisch erzeugt und an den passenden Stellen bereitgestellt. Hierbei spricht man auch vom Design Pattern der Inversion of Control.

Wie Beans in Spring sind Provider in Nest standardmäßig Singletons, d. h. es existiert im Kontext der Anwendung nur eine Instanz von ihnen. Natürlich können hier auch andere Scopes genutzt werden, wie etwa das Erstellen einer neuen Instanz pro Request.

Module

Das Modulsystem von Nest ist dem von Angular nachempfunden. Ein Modul definiert:

  • providers: eine Liste der Provider des Moduls
  • imports: die Liste der Module, welche das Modul selbst importiert
  • controllers: die Liste der Controller, welche das Modul definiert
  • exports: eine Liste an Providern, die dieses Modul exportiert, um sie, wenn das Modul in einem anderen Modul importiert wird, bereitzustellen.

Module in Nest sind Singletons.

Module können dynamisch nachladen werden. Standardmäßig werden alle Module „eager “, d .h. direkt geladen, was bei einer großen Anwendung zu einer sehr langen Startzeit der Applikation führen kann. Dies ist jedoch nicht in jedem Kontext vertretbar. In diesen Fällen können Module „lazy“, also dynamisch zur Laufzeit nachgeladen werden. Es gibt jedoch einige Einschränkungen: So können Module, welche Controller und damit Routen und Endpunkte definieren, natürlich nicht „lazy“  geladen werden.

Controller

Ein Controller behandelt einkommende Requests und gibt die dazugehörigen Responses zurück. Es handelt sich um eine TypeScript-Klasse, welche mit einem Decorator @Controller() versehen ist. Diese Controller-Klassen sind im Aufbau ähnlich zu Controllern in Spring:

Als Parameter für den @Controller() Decorator kann die Route, unter welcher der Controller Requests beantwortet, spezifiziert werden. @Controller(‘posts‘) definiert einen Controller unter /posts.

Die Methoden der Klasse können per Decorator genutzt werden, um einzelne HTTP-Verben oder Parameter zu verarbeiten. So beantwortet eine Methode annotiert mit dem @Get() Decorator GET-Requests.

Interessant an diesen Methoden ist, dass diese auch asynchron sein können, d. h. async/await können genutzt werden und Nest kümmert sich beim Aufruf der Methode um den Rest.

Folgendes Beispiel zeigt einen Controller in Nest.js:

CLI

Mit der Nest CLI können Nest Applikationen nicht nur generiert, gestartet und für Produktion gebaut werden, sondern es können auch Code-Artefakte, wie etwa Services, Module, Controller usw. generiert werden. Mit dem Befehl nest g <Artefakt> <Name> kann ein neues Artefakt mit einem bestimmten Namen im aktuellen Verzeichnis angelegt werden. Je nach Typ wird das neue Artefakt dann direkt im passenden Modul registriert.

Darüber hinaus bietet die CLI Unterstützung bei der Entwicklung von mehreren Anwendungen in einem Monorepository. Außerdem können in einem Monorepository mit der CLI Bibliotheken zur Nutzung mit Nest entwickelt werden.

Testing

Eine per Nest CLI generierte Anwendung kommt mit dem Testrunner jest vorinstalliert. Das Package @nestjs/testing bietet Unterstützung zum Schreiben von Tests. So gibt es die Möglichkeit ein sogenanntes TestingModule, also ein Modul, welches nur in Tests verwendet wird, anzulegen. Für dieses Modul können etwa Provider überschrieben werden. So lassen sich einfach Unit-Tests  schreiben.

Für Ende-zu-Ende-Tests kann mit einem TestingModule ein HTTP-Server gestartet werden, sodass man komplette HTTP-Requests und die zurückgelieferten Antworten testen kann:

Insbesondere für die Entwicklung von Enterprise-Anwendungen in mittleren bis großen Teams bietet Nest Features, die die Umsetzung einer einheitlichen Architektur ermöglichen und zur Code-Qualität und der Einhaltung von gemeinsamen Standards beitragen.


Sie planen ein Projekt mit Node.js oder sind bereits in der Umsetzung? Wir unterstützen Sie gerne.


zurück zur Blogübersicht

Diese Beiträge könnten Sie ebenfalls interessieren

Keinen Beitrag verpassen – viadee Blog abonnieren

Jetzt Blog abonnieren!

Kommentare

Christian Siebmanns

Christian Siebmanns

Christian Siebmanns ist Berater bei der viadee IT-Unternehmensberatung. Schwerpunkt seiner Arbeit ist der Einsatz in verschiedenen Kundenprojekten im Webumfeld. Christian ist Experte für Java und TypeScript.