nestjs-logo

Eine kompakte Einführung in NestJS

Keine Kommentare

Node.js hat die Sprache JavaScript in den letzten Jahren auf ein neues Niveau in der Entwicklung von Webapplikationen gehoben. Dadurch sind großartige Projekte wie Angular, React und Vue entstanden, die die Erstellung schneller, erweiterbarer sowie testbarer Applikationen ermöglichen. Auch im Backend-Bereich stehen für Node.js viele Bibliotheken, Helfer und Tools zur Verfügung. Jedoch beschäftigt sich keines davon intensiv mit dem Thema Architektur. Genau hier setzt das NestJS-Framework an, indem es uns out of the box eine Anwendungsarchitektur bereitstellt, mit der wir sehr einfach testbare, lose gekoppelte und leicht zu wartende Backend-Anwendungen erstellen können.

NestJS ist von Angular inspiriert. Es ist in TypeScript geschrieben und vereint Elemente der objektorientierten, funktionalen und reaktiven Programmierung. NestJS erfindet das Rad nicht neu, denn standardmäßig verwendet es unter der Haube das Express-Framework, stellt aber die Möglichkeit zur Verfügung, auch mit anderen Frameworks, wie z. B. Fastify, zusammenzuarbeiten.

In diesem Blog-Beitrag möchte ich euch eine kurze Einführung in NestJS geben. Dazu schauen wir uns die Building Blocks jeder NestJS-Applikation an und erstellen eine simple Web-API zur Verwaltung von Marketing-Artikeln (Hoodies, T-Shirts, Kugelschreiber etc.), die wir intern als „Swag“ bezeichnen.

Building Blocks

Wie schon erwähnt, ist NestJS von Angular inspiriert. Dementsprechend weist Nest große Ähnlichkeiten mit dem Google-Framework auf. Eigenschaften wie TypeScript-Support, Modularisierung sowie Dependency Injection (DI) wurden übernommen. Daraus ergeben sich die Building Blocks jeder NestJS-Applikation.

Controller

NestJS-Controller sind für die Verarbeitung von HTTP-Anfragen verantwortlich. Sie bieten eine einfache Möglichkeit, Routen für die Applikation zu definieren. Ein Controller wird mit einer TypeScript-Klasse beschrieben:

Der @Controller-Decorator kennzeichnet die Klasse als Controller und legt zugleich die Route fest. Die Art der HTTP-Anfrage wird an den Methoden spezifiziert. Dazu stellt uns NestJS unter anderem die Decorators @Get, @Post, @Put und @Delete zur Verfügung. Ein NestJS-Controller ist mit einer Angular-Komponente gleichzusetzen.

Provider

Wie Angular stellt uns auch NestJS einen DI-Mechanismus standardmäßig zur Verfügung. Elemente, auf die man über den DI-Container zugreifen kann, werden als Provider bezeichnet. Ein Provider kann also ein Service, eine Klasse, eine Funktion oder ein Wert sein. Provider können in einzelne Controller oder andere Provider injiziert werden. Um beispielsweise eine Klasse in den DI-Container aufzunehmen, muss diese den Decorator @Injectable besitzen:

Module

Module dienen hauptsächlich zur Organisation der Applikationsstruktur. In einem Modul werden Controller und Provider, die zusammen ein bestimmtes Feature-Set ergeben, zusammengefasst. Module können von anderen Modulen importiert werden und ermöglichen es so, die Applikation in bestimmte Bereiche aufzuteilen. Jede NestJS-Applikation hat mindestens ein Modul, das sogenannte App-Modul. Es dient als eine Art Sammelpunkt für Features, die in der Applikation zur Verfügung stehen sollen. Genauso wie in Angular ist ein Modul eine TypeScript-Klasse, die mit einem Decorator versehen ist. Statt @NgModule heißt der Decorator hier einfach nur @Module:

Projekt-Setup

Viele moderne JavaScript-Frontend-Frameworks werden heutzutage durch ein eigenständiges Command Line Interface (CLI) ergänzt, das bei der Einrichtung einer geeigneten Projektumgebung hilft. Die mühselige Installation und Konfiguration von Dev-, Test- sowie Build-Tools gehört der Vergangenheit an. Auch NestJS liefert uns für den reibungslosen Einstieg ein CLI. Mit diesem kann man nicht nur sehr einfach ein neues Projekt aufsetzen, sondern auch die zugehörigen Artefakte wie Controller, Services, Module etc. generieren. Das CLI wird über den Node Package Manager (npm) installiert:

npm install -g @nestjs/cli

Nach der Installation steht dann das CLI über den Befehl nest im Terminal zur Verfügung. Ein Aufruf mit dem Argument new erstellt ein neues Projekt:

nest new nest-swag-shop

Bei der Erstellung des Projekts fragt das CLI, welcher Package Manager (npm oder yarn) verwendet werden soll. Wir wählen hier npm. Danach kann die Applikation durch folgenden Aufruf im Projektverzeichnis gestartet werden:

npm run start:dev

Beim Starten werden die Bundles für den Programmcode generiert und TypeScript wird in JavaScript kompiliert. Unsere Anwendung steht uns dann über http://localhost:3000 zur Verfügung und gibt uns das bekannte „Hello World!“ zurück. Die Applikation läuft im sogenannten Watch-Mode und wird bei jeder Änderung neu gebaut.

Einführung NestJS - Hello World

NestJS am Beispiel einer simplen Web-API

Für unsere Swag-Verwaltung benötigen wir zuerst eine Model-Klasse, die einen Swag-Artikel in vereinfachter Form repräsentiert:

Als nächstes brauchen wir einen Service, der die eigentliche Verwaltung (Business-Logic) unseres Swags übernimmt. Services können wir mit folgendem Befehl über das CLI generieren lassen:

nest generate service swag

Das Kommando erstellt zunächst in src ein neues Verzeichnis mit dem Namen swag. In diesem Verzeichnis ist dann unser Service in der Datei swag.service.ts zu finden. Ein Service ist nichts anderes als ein Provider, also eine Klasse mit dem @Injectable-Decorator. Damit wird gekennzeichnet, dass der Service über den DI-Container zur Verfügung steht. Den Service erweitern wir um die benötigte Logik. Da wir ihn einfach halten wollen, verzichten wir hier auf eine Datenbankanbindung und verwalten den Swag im Speicher:

Für den Zugriff über HTTP benötigen wir als nächstes einen Controller, der auch mit dem Nest-CLI generiert werden kann:

nest generate controller swag

Der Controller wird um die passenden CRUD-Methoden ergänzt. Damit diese auch über HTTP ansteuerbar sind, werden sie mit den von NestJS zur Verfügung gestellten Decorators @Post, @Get, @Put und @Delete versehen. In den Decorators können mit der Doppelpunkt-Notation Path-Parameter spezifiziert werden, auf die man dann im Methodenrumpf mit dem @Param-Decorator zugreifen kann. Auf den Body des Requests greift man mit dem @Body-Decorator zu. Der Controller verwendet den zuvor erstellten Swag-Service, der über den Constructor injiziert wird. Der Rückgabewert einer Methode wird standardmäßig ins JSON-Format transformiert:

Damit lassen sich Swag-Elemente über HTTP erstellen, anzeigen, bearbeiten und löschen. Diese Funktionalität müssen wir jetzt noch der Applikation zur Verfügung stellen. Dazu erstellen wir ein neues Modul:

nest generate module swag

In dem Modul registrieren wir dann unseren Controller und Service:

Jetzt muss das Swag-Modul nur noch im App-Modul importiert werden:

Danach ist unser Swag unter http://localhost:3000/swags abrufbar:

Einführung NestJS - Endpoint für Swags

Das Anlegen, Bearbeiten und Löschen kann beispielsweise mit cURL getestet werden:

curl -X POST http://localhost:3000/swags -H 'Content-Type: application/json' -d '{ "title": "Snapback-Cappie", "description": "Baseball Cap für Männer, Frauen und Kinder mit dem codecentric Logo" }'
curl -X PUT http://localhost:3000/swags/4 -H 'Content-Type: application/json' -d '{ "title": "Snapback Cap", "description": "Baseball Cap mit dem codecentric Logo" }'
curl -X DELETE http://localhost:3000/swags/4

Fazit

Diese Einführung reißt nur einen sehr kleinen Teil der Funktionalität von NestJS an. Das Framework hat noch viel mehr zu bieten, unter anderem Support für GraphQL, WebSockets und Microservices. Angular-Entwickler werden sich sehr schnell mit dem Framework anfreunden, denn wer Angular kann, der kann auch NestJS. Aber auch Freunde aus der C#- und Java-Welt werden sich schnell zurechtfinden, da die Konzepte sehr ähnlich sind. Nach GitHub-Sternen ist es das am schnellsten wachsende Node.js-Framework 2018.


Ich hoffe, der Blog-Beitrag gibt euch genügend Informationen, um NestJS für euer nächstes Projekt in Betracht zu ziehen. Den Sourcecode für das Beispiel findet ihr auf GitHub und CodeSandbox.

Christian Binzer

Christian arbeitet seit 2017 als Software Engineer bei codecentric in Solingen. Er hilft unseren Kunden bei der Entwicklung von komplexen Web-Anwendungen, sowohl im Frontend als auch im Backend. Aktuell dreht sich bei ihm alles um JavaScript, TypeScript, Node.js und Angular.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.