Routing

Routing bezieht sich darauf, wie die Endpunkte einer Anwendung (URIs) auf Kundenanfragen reagieren. Für eine Einführung in das Routing siehe Basic routing.

Du definierst Routing, indem du Methoden des Express app Objekts verwendest, die den HTTP-Methoden entsprechen; zum Beispiel, app. et() um GET-Anfragen und app.post zu behandeln, um POST-Anfragen zu bearbeiten. For a full list, see app.METHOD. You can also use app.all() to handle all HTTP methods and app.use() to specify middleware as the callback function (See Using middleware for details).

These routing methods specify a callback function (sometimes called a “handler function”) that Express automatically runs when the application receives a request matching the specified route (endpoint) and HTTP method. Mit anderen Worten, die Anwendung “lauscht” für Anforderungen, die mit der angegebenen Route(s) und Methode(n) übereinstimmen und wenn es ein Spiel erkennt, ruft es die angegebene Callback-Funktion auf.

In der Tat können die Routing-Methoden mehr als eine Callback-Funktion als Argumente haben. Mit mehreren Callback-Funktionen, es ist wichtig, next als Argument für die Callback-Funktion zur Verfügung zu stellen und dann next() im Körper der Funktion aufzurufen, um die Steuerung an den nächsten Callback zu übergeben.

Der folgende Code ist ein Beispiel für eine sehr einfache Route.

index.cjs
const express = require('express');
const app = express();
// respond with "hello world" when a GET request is made to the homepage
app.get('/', (req, res) => {
res.send('hello world');
});

Routenmethoden

Eine Route-Methode wird von einer der HTTP-Methoden abgeleitet und an eine Instanz der Klasse `express angehängt.

Der folgende Code ist ein Beispiel für Routen, die für die GET und die POST Methoden im Root der App definiert sind.

// GET method route
app.get('/', (req, res) => {
res.send('GET request to the homepage');
});
// POST method route
app.post('/', (req, res) => {
res.send('POST request to the homepage');
});

Express unterstützt Methoden, die allen HTTP-Anfragemethoden entsprechen: get, post und so weiter. For a full list, see app.METHOD.

Es gibt eine spezielle Routing-Methode, app.all(), die benutzt wird, um Middleware-Funktionen an einem Pfad für all HTTP-Requestmethoden zu laden. For example, the following handler is executed for requests to the route "/secret" whether using GET, QUERY, POST, PUT, DELETE, or any other HTTP request method supported in the http module.

app.all('/secret', (req, res, next) => {
console.log('Accessing the secret section ...');
next(); // pass control to the next handler
});

Routenpfade

Routenpfade in Kombination mit einer Anfragemethode definieren die Endpunkte, an denen Anfragen gestellt werden können. Routenpfade können Strings oder reguläre Ausdrücke sein.

Note

Express verwendet path-to-regexp v8 um die Routenpfade zu treffen; lesen Sie die Dokumentation zu regexp für alle Möglichkeiten bei der Definition von Routenpfaden. Express Playground Router ist ein praktisches Werkzeug zum Testen grundlegender Express-Routen, obwohl es kein Muster-Matching unterstützt.

Stringpfade

String Pfade entsprechen exakt den Anforderungen. Der Punkt (.) und der Bindestrich (-) werden wörtlich interpretiert.

Warning

Abfragezeichenketten sind nicht Teil des Routenweges.
app.get('/', (req, res) => {
res.send('root');
});
app.get('/about', (req, res) => {
res.send('about');
});
app.get('/random.text', (req, res) => {
res.send('random.text');
});

Wildcards

Platzhalter entsprechen jedem Pfad nach einem Präfix. Sie müssen einen Namen haben, genau wie Routenparameter, und werden als Arrays von Pfadsegmenten erfasst.

app.get('/files/*filepath', (req, res) => {
// GET /files/images/logo.png
console.dir(req.params.filepath);
// => [ 'images', 'logo.png' ]
res.send(`File: ${req.params.filepath.join('/')}`);
});

Um auch dem Wurzelpfad zu entsprechen, wickeln Sie den Platzhalter in Klammern:

// Matches / , /foo , /foo/bar , etc.
app.get('/{*splat}', (req, res) => {
// GET / => req.params.splat = []
// GET /foo/bar => req.params.splat = [ 'foo', 'bar' ]
res.send('ok');
});

Optionale Segmente

Verwenden Sie Klammern um optionale Segmente in einem Routenpfad zu definieren. Wenn das Segment nicht vorhanden ist, wird der Parameter von req.params weggelassen.

app.get('/:file{.:ext}', (req, res) => {
// GET /image.png => req.params = { file: 'image', ext: 'png' }
// GET /image => req.params = { file: 'image' }
res.send('ok');
});

Die Zeichen ?, +, *, [] und () sind reserviert und können nicht als buchstäbliche Zeichen in Routenpfaden verwendet werden. Benutze \, um sie bei Bedarf zu maskieren.

Reguläre Ausdrücke

Sie können auch reguläre Ausdrücke als Routenpfade verwenden. Dies ist nützlich, wenn Sie eine komplexere Abgleichlogik benötigen.

// Matches any path containing "a"
app.get(/a/, (req, res) => {
res.send('/a/');
});
// Matches paths ending with "fly" (butterfly, dragonfly, etc.)
app.get(/.*fly$/, (req, res) => {
res.send('/.*fly$/');
});

Routenparameter

Routenparameter sind URL-Segmente, die zur Erfassung der an ihrer Position in der URL angegebenen Werte verwendet werden. Die erfassten Werte werden im Objekt req.params gefüllt, wobei der Name des im Pfad angegebenen Routenparameter als ihre jeweiligen Schlüssel angegeben ist.

Route path: /users/:userId/books/:bookId
Request URL: http://localhost:3000/users/34/books/8989
req.params: { "userId": "34", "bookId": "8989" }

Um Routen mit Routenparametern zu definieren, geben Sie einfach die Routenparameter im Pfad der Route, wie unten gezeigt, an.

app.get('/users/:userId/books/:bookId', (req, res) => {
res.send(req.params);
});

In TypeScript, @types/express infers the parameters from the route path, so in the handler above req.params.userId and req.params.bookId are already typed as string with no extra annotation. Reading a name that is not in the route (such as req.params.other) is a type error. You only need to annotate the parameters when the handler is defined separately from the route, because the type checker can no longer see the path. In that case, pass them as the first type argument of Request:

import { type Request, type Response } from 'express';
const sendParams = (req: Request<{ userId: string; bookId: string }>, res: Response) => {
res.send(req.params);
};
app.get('/users/:userId/books/:bookId', sendParams);

Der Name der Routenparameter muss aus “Wortzeichen” ([A-Za-z0-9_] ) bestehen.

Da die Bindestriche (-) und der Punkt (.) wörtlich interpretiert werden, können sie zusammen mit Routenparametern für nützliche Zwecke verwendet werden.

Route path: /flights/:from-:to
Request URL: http://localhost:3000/flights/LAX-SFO
req.params: { "from": "LAX", "to": "SFO" }
Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { "genus": "Prunus", "species": "persica" }

Regexp Zeichen werden in Routenpfaden nicht unterstützt. Verwenden Sie stattdessen ein Array von Pfaden oder regulären Ausdrücken. Weitere Informationen finden Sie in der Syntax Pfadroute Match .

Routenhandler

Du kannst mehrere Callback-Funktionen bereitstellen, die sich wie middleware verhalten um eine Anfrage zu bearbeiten. Die einzige Ausnahme ist, dass diese Callbacks next('route') aufrufen könnten, um die restlichen Rufnummern zu umgehen. Sie können diesen Mechanismus nutzen, um Vorbedingungen auf einer Route aufzuerlegen, dann die Kontrolle an die nachfolgenden Routen übergeben, wenn es keinen Grund gibt, mit der aktuellen Route fortzufahren.

app.get('/user/:id', (req, res, next) => {
if (req.params.id === '0') {
return next('route');
}
res.send(`User ${req.params.id}`);
});
app.get('/user/:id', (req, res) => {
res.send('Special handler for user ID 0');
});

In diesem Beispiel:

  • GET /user/5 → behandelt durch die erste Route → sendet “Benutzer 5”
  • GET /user/0 → erste Routenaufrufe next('route'), überspringt zur nächsten passenden /user/:id Route

Routenhandler können in Form einer Funktion, eines Arrays von Funktionen oder Kombinationen beider sein, wie in den folgenden Beispielen gezeigt.

Eine einzelne Callback-Funktion kann eine Route handhaben. Zum Beispiel:

app.get('/example/a', (req, res) => {
res.send('Hello from A!');
});

Mehr als eine Callback-Funktion kann eine Route handhaben (stelle sicher, dass du das next Objekt angibst). Zum Beispiel:

app.get(
'/example/b',
(req, res, next) => {
console.log('the response will be sent by the next function ...');
next();
},
(req, res) => {
res.send('Hello from B!');
}
);

Ein Array von Callback-Funktionen kann eine Route handhaben. Zum Beispiel:

const cb0 = function (req, res, next) {
console.log('CB0');
next();
};
const cb1 = function (req, res, next) {
console.log('CB1');
next();
};
const cb2 = function (req, res) {
res.send('Hello from C!');
};
app.get('/example/c', [cb0, cb1, cb2]);

Eine Kombination aus unabhängigen Funktionen und Arrays von Funktionen kann eine Route handhaben. Zum Beispiel:

const cb0 = function (req, res, next) {
console.log('CB0');
next();
};
const cb1 = function (req, res, next) {
console.log('CB1');
next();
};
app.get(
'/example/d',
[cb0, cb1],
(req, res, next) => {
console.log('the response will be sent by the next function ...');
next();
},
(req, res) => {
res.send('Hello from D!');
}
);

Antwortmethoden

Die Methoden auf dem Antwortobjekt (res) in der folgenden Tabelle können eine Antwort an den Client senden und den Request-Antwort-Zyklus beenden. Wenn keine dieser Methoden von einem Routenhandler aufgerufen wird, bleibt die Client-Anfrage hängen.

MethodeBeschreibung
res.download()Fordern Sie eine Datei zum Download an.
res.end()Beenden Sie den Antwort-Prozess.
res.json()Sende eine JSON-Antwort.
res.jsonp()Senden Sie eine JSON-Antwort mit JSONP-Unterstützung.
res.redirect()Anfrage umleiten.
res.render()Render a view template.
res.send()Senden Sie eine Antwort von verschiedenen Typen.
res.sendFile()Senden Sie eine Datei als octet-Stream.
res.sendStatus()Legen Sie den Antwort-Statuscode fest und senden Sie seine Zeichenfolge Repräsentation als Antwortkörper.

app.route()

Sie können verkettende Routenhandler für einen Routenpfad erstellen, indem Sie app.route() verwenden. Da der Weg an einem einzigen Ort angegeben wird, ist die Schaffung modularer Routen hilfreich, ebenso wie die Reduzierung von Redundanz und Typos. Weitere Informationen über Routen finden Sie unter Router() documentation.

Hier ist ein Beispiel für verkettete Routenhandler, die mit app.route() definiert werden.

app
.route('/book')
.get((req, res) => {
res.send('Get a random book');
})
.post((req, res) => {
res.send('Add a book');
})
.put((req, res) => {
res.send('Update the book');
});

express.Router

Verwende die Klasse express.Router, um modulare mountbare Routenhandler zu erstellen. Eine Router-Instanz ist ein komplettes Middleware- und Routing-System; aus diesem Grund wird sie oft als “Mini-App” bezeichnet.

Das folgende Beispiel erzeugt einen Router als Modul, lädt eine Middleware-Funktion darin definiert einige Routen und mountet das Router-Modul auf einem Pfad in der Hauptanwendung.

Erstelle eine Router-Datei namens birds.js im App-Verzeichnis, mit folgendem Inhalt:

birds.cjs
const express = require('express');
const router = express.Router();
// middleware that is specific to this router
const timeLog = (req, res, next) => {
console.log('Time: ', Date.now());
next();
};
router.use(timeLog);
// define the home page route
router.get('/', (req, res) => {
res.send('Birds home page');
});
// define the about route
router.get('/about', (req, res) => {
res.send('About birds');
});
module.exports = router;

Laden Sie dann das Router-Modul in der App:

index.cjs
const birds = require('./birds');
// ...
app.use('/birds', birds);

Die App wird nun in der Lage sein, Anfragen an /birds und /birds/about zu bearbeiten, aufrufen sowie die Middleware-Funktion timeLog aufrufen, die spezifisch für die Route ist.

Aber wenn die übergeordnete Route /birds Pfadparameter hat, wird sie standardmäßig nicht von den Unterrouten aus erreichbar sein. To make it accessible, you will need to pass the mergeParams option to the Router constructor reference.

const router = express.Router({ mergeParams: true });