Abschnitt 9 · Lektion 2
Die ersten Routen
Eine Route besteht aus einer Methode und einem Pfad, genau wie in Abschnitt 8. Nur schreibt man sie jetzt hin, statt sie abzufragen.
express, get, post, listen
import express from "express";
const app = express();
app.get("/notizen", (req, res) => res.json({ anzahl: 2 }));
app.post("/notizen", (req, res) => res.status(201).json({ angelegt: true }));
app.get("/notizen/erste", (req, res) => res.json({ notiz: "Milch kaufen" }));
app.get("/", (req, res) => res.send("Notizbuch"));
app.listen(3000); express() erzeugt die Anwendung. app.get(pfad, funktion) legt eine Route für GET an,
app.post eine für POST, und es gibt für jede Methode eine solche Funktion. app.listen(port)
startet den Server und ist dasselbe listen wie in Abschnitt 8, denn es ist dasselbe Objekt
darunter.
Die Funktion bekommt req und res, wie gehabt. Neu ist nur, dass sie erst aufgerufen wird, wenn
Methode und Pfad schon geprüft sind. Die ganze if-Kette aus 8.5 ist damit weg.
Rechts steht /, also die letzte der vier Routen. Die anderen drei erreichst du über die
Adresszeile und über das Terminal, und die POST-Route geht nur dort:
curl -i http://localhost:3000/notizen
curl -i -X POST http://localhost:3000/notizen
curl -i http://localhost:3000/notizen/erste
Von oben nach unten, die erste passende gewinnt
Das ist die wichtigste Regel dieser Lektion, und sie ist der Unterschied zu einer Verzweigung, wie du sie bisher geschrieben hast.
Eine switch-Anweisung springt direkt zum passenden Fall. Express macht etwas anderes: Es geht
seine Liste der Reihe nach durch und nimmt die erste Route, die passt. Was danach kommt, sieht
es nie an.
Solange alle Pfade fest und verschieden sind, merkt man davon nichts. Sobald sich zwei Routen überschneiden, ist die Reihenfolge die ganze Semantik.
import express from "express";
const app = express();
// Diese Middleware steht ganz oben und antwortet auf alles. Was darunter
// kommt, wird nie erreicht.
app.use((req, res) => res.send("ich war zuerst da"));
app.get("/notizen", (req, res) => res.json({ anzahl: 2 }));
app.listen(3000); app.use ohne Pfad passt auf jede Anfrage. Ganz oben notiert macht es alles darunter tot, und
zwar lautlos: kein Fehler, keine Warnung, die Route ist einfach nie dran. Ruf /notizen auf, wo
laut Code eine Zahl stehen müsste, und es kommt trotzdem „ich war zuerst da”. Wenn du jemals einen
Server debuggst, bei dem eine Route partout nicht aufgerufen wird, obwohl sie richtig geschrieben
ist, dann schau nach, was über ihr steht.
Der Standardfall
Express bringt einen 404 mit, du hast ihn in 9.1 gesehen. Für eine Seite ist er in Ordnung, für eine
Datenschnittstelle nicht: Er schickt eine kleine HTML-Seite, und ein Aufrufer, der JSON erwartet und
<!DOCTYPE html> bekommt, hat ein Problem beim Auswerten.
Deshalb ersetzt man ihn fast immer.
import express from "express";
// So steht es in aelteren Anleitungen, und seit Express 5 geht es nicht mehr.
try {
express().all("*", (req, res) => res.send("ok"));
} catch (fehler) {
console.log(`app.all("*") wirft: ${fehler.message.split(";")[0]}`);
}
const app = express();
app.get("/notizen", (req, res) => res.json({ anzahl: 2 }));
// Der eigene Standardfall: eine Middleware ganz unten, ohne Pfad.
app.use((req, res) => res.status(404).json({ fehler: "nicht gefunden" }));
app.listen(3000); Das Mittel dafür ist dasselbe app.use ohne Pfad wie im Beispiel davor, nur eben ganz unten.
Steht es oben, verschluckt es alles. Steht es unten, kommt es genau dann dran, wenn keine Route
gepasst hat. Derselbe Baustein, zwei völlig verschiedene Wirkungen, allein durch die Position.
Rechts steht /notizen. Tipp /nix in die Adresszeile, und statt der Fehlerseite von Express
kommt jetzt dein JSON. Im Terminal siehst du dazu den Statuscode und den Inhaltstyp:
curl -i http://localhost:3000/nix
Eine Falle aus alten Anleitungen
Eine Zeile im Beispiel oben ist bewusst so stehen geblieben. app.all("*", ...) wirft seit
Express 5 einen Fehler.
Das ist bemerkenswert, weil genau diese Zeile in unzähligen Tutorials, Antworten und Vorlagen steht.
Sie stammt aus Express 4, wo * ein gültiges Muster war. Express 5 benutzt eine neuere Fassung des
Pfad-Übersetzers, und der verlangt, dass ein Platzhalter einen Namen hat: app.all("*splat", ...)
funktioniert, app.all("/*splat", ...) auch.
Merk dir vor allem das Verhalten: Der Fehler kommt beim Anlegen der Route, also sofort beim Start und nicht erst bei einer Anfrage. Deshalb steht die abgefangene Meldung im Terminal, obwohl niemand den Server gefragt hat. Das ist die freundliche Variante, denn so fällt es dir beim ersten Ausführen auf statt einem Nutzer im Betrieb.
Und merk dir die allgemeine Lehre daraus, sie gilt weit über diese eine Zeile hinaus: Wenn du eine Anleitung im Netz findest, prüf, für welche Hauptversion sie geschrieben ist. In diesem Kurs ist es Express 5.
Am einfachsten umgehst du das Ganze, indem du für den Standardfall gar kein Muster benutzt, sondern
app.use ohne Pfad. Das sieht in beiden Versionen gleich aus.
Zum Mitnehmen
Routen werden von oben nach unten geprüft, die erste passende gewinnt. Und app.all mit einem nackten Stern wirft seit Express 5 einen Fehler.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
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 3 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.