Friedrich Siever

9. Januar 2024

Nest.js - Der einfache Einstieg

von: Friedrich Siever | Last Updated: 09.01.24

Intro

Der Anfang ist oft der schwierigste Teil. Doch mit Fortschritten in der Technologie wird auch der Einstieg in scheinbar komplexe Bereiche wie die Backendentwicklung mit Node.js zunehmend leichter. Insbesondere, wenn man sich für die Entwicklung mit Nest.js entscheidet. Dieses Intro ist darauf ausgerichtet, die essenziellen Schritte für einen unkomplizierten Einstieg in Nest.js zu präsentieren – ein Beitrag, der sich auf praktische Anwendung konzentriert. Wenn du mehr über die Grundlagen von Nest.js erfahren möchtest, empfehle ich dir zunächst den Beitrag Nest.js Grundlagen zu lesen.

Das Vorgehen

Hier sind die wesentlichen Schritte für den Einstieg in Nest.js:

  1. Installation von Nest CLI: Beginne mit der Installation von Nest CLI, dem Command Line Tool für Nest-Projekte. Dieses Werkzeug erleichtert die Verwaltung und den Aufbau von Nest-Anwendungen.

  2. Erstellen eines brandneuen Projektes: Nutze die neu installierte Nest CLI, um ein frisches Nest.js-Projekt zu erstellen. Dieser Schritt bildet die Grundlage für deine Anwendung.

  3. Verständnis der Verzeichnisstruktur: Nimm dir Zeit, um die Verzeichnisstruktur deines neuen Nest-Projekts zu erkunden. Dies umfasst die typischen Bestandteile von Nest-Anwendungen, wie zum Beispiel Controller, Module und Services. Ein grundlegendes Verständnis dieser Struktur wird dir helfen, dich in deinem Projekt zurechtzufinden und effizient zu arbeiten.

Die Nest CLI

Nest CLI ist das Command Line Tool, das dir dabei hilft, Nest.js-Anwendungen zu erstellen und zu entwickeln. Obwohl die Verwendung dieser CLI-Tools nicht zwingend erforderlich ist, sind sie äußerst nützlich. Persönlich nutze ich sie regelmäßig. Um diese hilfreichen Tools verwenden zu können, musst du sie zuerst installieren. Mit npm geht das folgendermaßen:

npm install -g @nestjs/cli

Der Prozess kann einige Sekunden dauern. Wenn die Installation abgeschlossen ist, kannst du wie folgt überprüfen, ob alles geklappt hat.

nest --help

Der Aufruf sollte dir eine Liste in der Konsole ausspielen, die alle nest cli Kommandos enthält. Das sollte in Etwa so aussehen.

namealiasdescription
applicationappGenerate a new application workspace
classclGenerate a new class
configurationconfigGenerate a CLI configuration file
controllercoGenerate a controller declaration
decoratordGenerate a custom decorator
filterfGenerate a filter declaration
gatewaygaGenerate a gateway declaration
guardguGenerate a guard declaration
interceptoritcGenerate an interceptor declaration
interfaceitfGenerate an interface
librarylibGenerate a new library within a monorepo
middlewaremiGenerate a middleware declaration
modulemoGenerate a module declaration
pipepiGenerate a pipe declaration
providerprGenerate a provider declaration
resolverrGenerate a GraphQL resolver declaration
resourceresGenerate a new CRUD resource
servicesGenerate a service declaration
sub-appappGenerate a new application within a monorepo

Nest.js App erstellen

Der nächste natürliche Schritt ist die Erstellung einer Nest.js App, und das geht folgendermaßen.

nest new <projekt-name-hier-einfuegen>

Mit dieser einfachen Zeile werden initial einige Dateien erstellt, und du wirst nach dem Package Manager deiner Wahl gefragt. Stelle sicher, dass der ausgewählte Package Manager auch installiert ist. Andernfalls wird es nicht funktionieren. Der Prozess kann einen Moment dauern, bis er abgeschlossen ist.

Nest.js App starten

Danach wechsle in den neu erstellten Ordner deines Projekts und starte deinen Entwicklungsserver.

cd <projekt-name-hier-einfuegen>
npm run start:dev

Nachdem du das Nest.js-Projekt gestartet hast, dauert es einige Sekunden, bis es kompiliert wird. Sobald du die Meldung “Nest application successfully started” liest, bedeutet dies, dass deine App nun unter localhost:3000 erreichbar ist. Das kannst du einfach mit deinem Browser überprüfen. Su solltest einfach eine “Hello World” Message sehen.

Übrigens: Wenn du Interesse hast, tiefer in die Materie der Nest CLI einzusteigen, empfehle ich dir die wirklich fantastische Dokumentation der CLI Command References.

Die Projektstruktur

Dein brandneues Nest-Projekt folgt einer bestimmten Struktur, die ich dir nun vorstellen möchte. Wenn nichts verändert wurde (standardmäßig), handelt es sich um den sogenannten Standardmodus. Das bedeutet einfach, dass dein Repository dazu genutzt wird, eine einzelne Applikation zu erstellen.

Darüber hinaus unterstützt Nest einen sogenannten Monorepo-Modus. In diesem Modus fungiert ein Code-Repository als Heimat für eine größere Menge von Projekten. Diese Projekte teilen sich den Großteil des sogenannten “Common Code”. Das bezieht sich auf den Code, der von mehreren Projekten gemeinsam genutzt wird. Durch die Nutzung eines Monorepos können Entwickler Code effizienter wiederverwenden und konsistenter verwalten, da Änderungen an gemeinsamem Code an zentraler Stelle vorgenommen werden.

Der Root-Ordner des Projekts

Im Root-Ordner findest du wichtige Konfigurationsdateien wie tsconfig.json für TypeScript. Hier wird definiert, wie TypeScript zu JavaScript transpiliert wird. Auch die package.json ist hier zu finden, in der die Projekt-Dependencies spezifiziert werden. Zusätzlich werden hier wichtige von Nest.js vordefinierte Scripts aufgelistet.

{
   ...
    "scripts": {
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
   ...
}

Diesse können wie folgt einfach gestartet werden:

npm run <command-name>

Die package.json-Datei enthält auch die Jest-Konfiguration. Jest ist eine Testbibliothek, deren Umfang den Rahmen dieses Beitrags sprengen würde.

Auch das spannende Thema der Nest.js-App-Tests werde ich in einem eigenständigen Beitrag ausführlich behandeln.

Der src-Ordner

Hier befindet sich der Quellcode deiner Applikation. Die Datei main.ts spielt dabei eine besonders wichtige Rolle – sie ist der Entry-Point deiner Anwendung.

// src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}

bootstrap();

Die bootstrap-Funktion in dieser Datei sorgt dafür, dass ein neues Nest-Application-Objekt angelegt wird. Anschließend startet sie den Server, der auf den spezifizierten Port (standardmäßig 3000) hört.

Module

Wenn wir über den Applikationscode sprechen, sind die zentralen Bausteine von Nest.js Anwendungen die sogenannten Module. Module sind grundlegende Elemente, die dazu dienen, verschiedene Teile deiner Anwendung zu organisieren und zu strukturieren. Mit zunehmender Größe deiner Anwendung wirst du wahrscheinlich separate Module erstellen, um deinen Code besser zu organisieren. Diese Module können verschiedene Bestandteile enthalten, darunter:

  • Controllers
  • Services
  • Tests
  • Entities
  • und mehr

In diesem frühen Stadium gibt es jedoch nur ein einziges Modul. Jedes Modul ist in einer eigenen Datei definiert. In unserem Fall ist das app.module.ts.

// app.module.ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Das Modul ist eine Klasse die mit einem Dokorator annotiert wird. Sollte dir das Konzept der Dekoratoren nicht bekannt sein, empfehle ich dir den Beitrag zu TypeScript - Decorators von Rainald Menge-Sonnentag.

Nest.js greift sehr häufig auf das Konzept von Decorators zurück und fast die gesamte Funktionalität und die Moduleigenschaften können über Klassendekoratoren definiert werden. Wie diesen hier.

Controller

Ein wichtiger und ganz typischer Bestandteil der Nest.js-Module ist der Controller. Die Controller spielen in Nest.js eine zentrale Rolle bei der Definition von Routen und Endpunkten für deine Anwendung. Hier ist ein Beispiel für einen einfachen Controller, den wir mit der Nest CLI erstellt haben:

// src/app.controller.ts
import { Controller, Get } from "@nestjs/common";
import { AppService } from "./app.service";

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

Im vorliegenden Beispiel reagiert der Controller geschickt auf HTTP-GET-Requests und ruft dabei die getHello-Methode des zugehörigen Service auf. Durch die harmonische Zusammenarbeit von Controller und Service ergibt sich eine klar strukturierte und effektive Handhabung von HTTP-Anfragen in deiner Nest.js-Anwendung. Weitere Einblicke und eine detaillierte Beschreibung zu den Controllern in Nest.js findest du hier.

Service

Ein weiterer wichtiger Bestandteil in Nest.js-Modulen ist der Service. Die Klasse des Service ist der Ort, an dem du die Business-Logik deiner Anwendung schreibst oder besser gesagt auslagerst. Im Gegensatz zu Controllern ist ein Service nicht direkt mit HTTP-Anfragen verbunden und sendet auch keine HTTP-Responses. Hier ein Beispiel für einen einfachen Service:

// src/app.service.ts
import { Injectable } from "@nestjs/common";

@Injectable()
export class AppService {
  getHello(): string {
    return "Hello World!";
  }
}

In diesem Beispiel enthält der Service die Methode getHello, die eine einfache “Hello World!”-Nachricht zurückgibt. Services in Nest.js ermöglichen die saubere Trennung von Geschäftslogik, die in Controllern verwendet wird. Diese Strukturierung erleichtert die Wiederverwendung von Code und verbessert die Möglichkeiten für das Testen.

Unit Tests

Eine weitere wichtige Art von Tests sind Unit Tests. Diese sollten idealerweise nahe am Originalcode positioniert sein, den sie testen. Zum Beispiel befindet sich das Testfile für den App Controller in der Datei app.controller.spec.ts:

// src/app.controller.spec.ts
import { Test, TestingModule } from "@nestjs/testing";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";

describe("AppController", () => {
  let appController: AppController;

  beforeEach(async () => {
    const app: TestingModule = await Test.createTestingModule({
      controllers: [AppController],
      providers: [AppService],
    }).compile();

    appController = app.get<AppController>(AppController);
  });

  describe("root", () => {
    it('should return "Hello World!"', () => {
      expect(appController.getHello()).toBe("Hello World!");
    });
  });
});

Wenn du den Code im Moment noch nicht vollständig verstehst, lass dich nicht entmutigen.

In Zukunft werde ich detailliertere Beiträge zu einzelnen Themen wie Modulen, Controllern und Tests verfassen.

Der test-Ordner

Neben dem src-Ordner auf gleicher Höhe findest du außerdem einen test-Ordner. Dieser dient als Heimat für End-to-End-Tests.

Fazit

Zusammenfassend lässt sich festhalten:

  • Der Startpunkt deiner Anwendung ist die main.ts-Datei, die die Applikation initialisiert.
  • Nest-Anwendungen bestehen aus Modulen und haben mindestens ein Hauptmodul, das standardmäßig AppModule genannt wird.
  • Ein Modul setzt sich aus Controllern, Services, Entitäten und anderen kleineren Elementen zusammen.
  • Module werden in eigenen Moduldateien definiert, wobei der Klassendekorator @Module verwendet wird, um sie zu beschreiben.
0
0 Bewertungen

Jetzt selbst bewerten