From 7277f79aa5ed859617bcba05ed3f3ef27af9f7bb Mon Sep 17 00:00:00 2001 From: Denis Ergin Date: Sun, 2 Mar 2025 12:09:37 +0100 Subject: [PATCH] chore(slides): finalize fastify slides --- .../slides/node-backend/fastify.astro | 124 +++++++++++++++++- 1 file changed, 123 insertions(+), 1 deletion(-) diff --git a/src/components/slides/node-backend/fastify.astro b/src/components/slides/node-backend/fastify.astro index 6bace6f..8bc9e2e 100644 --- a/src/components/slides/node-backend/fastify.astro +++ b/src/components/slides/node-backend/fastify.astro @@ -15,5 +15,127 @@

Das wichtigste aus meiner Sicht: Eine solide TypeScript Unterstützung.

- +
+

Setup

+
+ +
+

Fastify hat eine CLI die leider nicht sehr gut Dokumentiert ist, obwohl diese Optionen hat um ein Fastify-Projekt extrem schnell aufzusetzen.

+

Folgender Befehl erstellt ein Fastify-Projekt in einen neuen Order "my-new-project" inklusive TypeScript-Unterstützung

+

+      # Projekt generieren
+      npx fastify-cli generate my-new-project -- --lang=ts
+
+      # Ins Projekt wechseln und Dependencies installieren
+      cd my-new-project
+      npm install
+
+      # Dev-Server starten
+      npm run dev
+    
+
+ +
+

Das Basis-Projekt sieht nach der Initialisierung folgendermaßen aus:

+

+      src/
+      ├── plugins/
+      │   ├── sensible.ts
+      │   └── support.ts
+      ├── routes/
+      │   ├── example/
+      │   │   └── index.ts
+      │   └── root.ts
+      └── app.ts
+      test/
+      ├── plugins/
+      │   └── ...
+      └── routes/
+          └── ...
+    
+
+ +
+

Routen

+
+ +
+

Im Ordner src/routes befindet sich die gesamte Routen-Logik innerhalb von fastify.

+

Mit dem CLI-Setup wurde das Projekt so konfiguriert, dass die Ordner und Dateien später den aufrufbaren Pfaden für die API entsprechen.

+

Konkret bedeutet dies: Die Datei im Pfad routes/example/index.ts wird über den URL-Pfad /example ansprechbar sein.

+
+ +
+

Innerhalb der Dateien kann der Pfad aber nochmal erweitert werden.

+

+      import { FastifyPluginAsync } from "fastify"
+
+      const example: FastifyPluginAsync = async (fastify, opts): Promise => {
+        fastify.get('/', async function (request, reply) {
+          return 'this is an example'
+        })
+      }
+
+      export default example;
+    
+
+ +
+

Fastify basiert stark auf einem Plug-And-Play basiertem Subsystem, um ein korrektes Typing zu haben, verwenden wir TypeScript-Types

+

"example" ist eine Variable die als Plugin-Funktion exportiert wird. Die Funktion nimmt das "globale" fastify-Objekt (und dessen konfiguration an). Zusätzlich erhalten wir weitere Optionen.

+
+ +
+

Innerhalb unseres Plugins haben wir dann die Möglichkeit (Unter)-Routen auf Basis des aktuellen Pfades zu erstellen.

+

fastify.get(...) legt einen GET-Handler auf einer Route an. Die Konfiguration erfolgt im Aufruf der Funktion "get".

+

Der erste Parameter beschreibt die Pfad-Erweiterung (basierend auf dem Ordner im routes-Ordner).

+

Der zweite Paramter ist eine Callback-Funktion die aufgerufen wird, wenn die Route durch einen Client aufgerufen wird.

+
+ +
+

Innerhalb dieses Callbacks können wir dann unsere Routen-Logik implementieren.

+
+ +
+

Plugins

+
+ +
+

In dem generierten Projekt gibt es noch einen 2. Ordner mit dem Namen "plugins".

+

Die hier erstellten Dateien legen Funktionen in den fastify-Scope die wir später in den Route-Handlers wiederverwenden können.

+

Unter anderem können wir hiermit Datenbank-Verbindungen als Plugins bereitstellen die wir später dazu verwenden um Datenbankabfragen zu machen.

+
+ +
+

Dynamische Routen

+
+ +
+

Wenn Routen einen dynamischen Anteil haben (also ein Teil des Pfades ist dynamisch mit zum Beispiel einer ID die wir abfragen), lässt sich dies simpel darstellen.

+

+      fastify.get('/:name', async function (request, reply) {
+        return `Hello, ${request.params.name}!`;
+      });
+    
+

Nun ist aber request.params.name Fehlerhaft.

+
+ +
+

Da wir mit TypeScript arbeiten, müssen wir der Funktion nun noch mitteilen, dass wir einen solchen Paramater erwarten:

+

+      type HelloNamedParams = {
+        name: string;
+      }
+      // ...
+      fastify.get<{
+        Params: HelloNamedParams;
+      }>('/:name', async function (request, reply) {
+        return `Hello, ${request.params.name}!`;
+      });
+    
+
+ +
+

Mit denn weiteren Optionen Body, Querystring und Headers können wir auch die erwartete Form dieser Request-Bestandteile definieren.

+
\ No newline at end of file