mitmario.dev

Was jetzt?

Node.js Sandbox 3 Min Lesezeit 2 BeispieleLektion 5 von 7

Achtzehn Abschnitte, und die Frage am Ende ist immer dieselbe: was davon brauche ich als Nächstes, und was ist nur laut? Diese Lektion ist der Wegweiser, den mir damals niemand gegeben hat. Zu jedem Punkt steht dabei, woran du merkst, dass du ihn jetzt brauchst, denn das ist die eigentliche Frage.

TypeScript, und warum jetzt und nicht vorher

Dieselbe Funktion, einmal mit Typen
export function rabatt(preis: number, prozent: number): number {
  // Die beiden Pruefungen bleiben. Typen gelten beim Uebersetzen, und
  // ein JSON aus einer Anfrage ist zur Laufzeit trotzdem alles Moegliche.
  if (!Number.isFinite(preis) || preis < 0) {
    throw new TypeError("preis muss eine Zahl ab 0 sein");
  }

  if (!Number.isInteger(prozent) || prozent < 0 || prozent > 100) {
    throw new RangeError("prozent muss zwischen 0 und 100 liegen");
  }

  return Math.round(preis * (100 - prozent)) / 100;
}

// rabatt("20", 10) laesst sich jetzt gar nicht mehr uebersetzen:
// Argument of type 'string' is not assignable to parameter of type 'number'.

Von allem, was hier steht, bringt TypeScript am meisten. Es ist JavaScript mit Angaben darüber, was wo hineingehört, und ein Übersetzer, der prüft, ob das stimmt. Der Nutzen ist nicht, dass Fehler verschwinden, sondern wann sie auffallen: beim Tippen statt im Betrieb.

Warum nach diesem Kurs und nicht davor: Weil du sonst zwei Dinge gleichzeitig lernst und bei jedem Problem raten musst, ob es an Node liegt oder an den Typen. Jetzt kennst du Node, und TypeScript ist eine Schicht darüber statt ein zweites Rätsel.

Und der Vorbehalt, den viele Einführungen weglassen: Typen gelten beim Übersetzen. Ein JSON aus einer Anfrage ist zur Laufzeit weiterhin alles Mögliche, deshalb bleiben die Prüfungen aus Abschnitt 15 genau da, wo sie sind. TypeScript ersetzt sie nicht, es beschreibt nur, was danach gilt.

Du brauchst es, sobald du eine Datei nach zwei Wochen wieder aufmachst und erst im Code nachsehen musst, was eine Funktion eigentlich zurückgibt.

Ein Datenbankwerkzeug, und warum SQL trotzdem

Derselbe Zugriff, einmal mit Werkzeug
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";

// Der eigentliche Gewinn steht hier: Die Tabelle ist einmal
// beschrieben, und ab jetzt kennt dein Editor die Spaltennamen.
// Ein Tippfehler in "titel" faellt beim Schreiben auf statt zur Laufzeit.
export const buecher = sqliteTable("buecher", {
  id: integer("id").primaryKey(),
  titel: text("titel").notNull(),
  jahr: integer("jahr"),
});

Werkzeuge wie Drizzle oder Prisma bauen Abfragen aus Bausteinen statt aus Text und kennen dabei deine Tabellen. Zwei Dinge werden dadurch spürbar besser: Der Editor schlägt Spaltennamen vor, und Änderungen am Schema bekommen einen geordneten Weg.

Was sich nicht ändert: Was diese Abfrage tut, entscheidest weiterhin du. Ein Werkzeug, dessen SQL du nicht lesen kannst, ist kein Vorteil, sondern eine Schicht zwischen dir und dem Problem. Deshalb war SQL zuerst dran und nicht danach. Wer Abschnitt 12 verstanden hat, kann ein solches Werkzeug in einem Nachmittag benutzen. Andersherum funktioniert es nicht.

Du brauchst es, sobald dein Projekt mehr als eine Handvoll Tabellen hat und du anfängst, Änderungen am Schema von Hand nachzuziehen.

Vier weitere, kurz und mit dem Moment dazu

Ein Framework mit mehr Meinung (Fastify, Nest, Hono). Express lässt dir alles offen, und das war für diesen Kurs richtig: Du hast jede Entscheidung selbst getroffen. Ein Framework mit mehr Meinung nimmt dir Entscheidungen ab und gibt dir dafür Struktur, Validierung und Geschwindigkeit als Standard. Du brauchst es, sobald ihr zu dritt an derselben Anwendung baut und jeder die Fehlerbehandlung anders löst.

Container (Docker). Immer dieselbe Umgebung, überall. Löst genau das und sonst nichts, wie in der letzten Lektion beschrieben. Du brauchst sie, sobald du zum zweiten Mal einen Fehler suchst, der sich mit „bei mir geht es” beschreiben lässt.

Warteschlangen und Hintergrundarbeit (BullMQ und Verwandte). Manche Arbeit dauert länger, als eine HTTP-Anfrage warten darf: ein Bild umrechnen, eine große Datei einlesen, hundert E-Mails verschicken. Statt den Aufrufer warten zu lassen, legst du einen Auftrag in eine Warteschlange und antwortest sofort mit 202. Du brauchst sie, sobald eine Route regelmäßig über zwei Sekunden läuft und du anfängst, an Timeouts zu drehen.

WebSockets (oder Server-Sent Events). HTTP funktioniert so: Der Aufrufer fragt, der Server antwortet. Soll der Server von sich aus etwas schicken, reicht das nicht, und dann brauchst du eine Verbindung, die offen bleibt. Du brauchst sie, sobald du überlegst, ob der Browser alle zwei Sekunden nachfragen soll. Für den einfachen Fall reichen Server-Sent Events und die sind deutlich weniger Arbeit.

Und was wirklich hilft

Nichts davon lernt sich aus einer Liste. Was hilft, ist ein eigenes Projekt, das dich interessiert, und zwar ein kleines: eine Verwaltung für etwas, das du selbst sammelst, ein Werkzeug für einen Handgriff, der dich nervt. Du hast in diesem Kurs jeden Baustein einmal von Hand gebaut, und genau deshalb kannst du jetzt entscheiden, welchen du dir abnehmen lässt.

Die nächste Lektion ist so ein Projekt, und es ist das größte des Kurses.

Zum Mitnehmen

Die beiden Beispiele hier sind zum Lesen und nicht zum Ausführen. Beide bräuchten eine Werkzeugkette, die dieser Kurs bewusst nicht aufbaut, und genau darum geht es: zu sehen, was sie ändern würden, bevor du sie dir holst.

Jetzt du

Basis Konto, kostenlos

Im Editor änderst du die Beispiele dieser Lektion und lässt sie gleich laufen. So merkst du am schnellsten, ob es sitzt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 2 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.