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.
const express = require('express');const app = express();
// respond with "hello world" when a GET request is made to the homepageapp.get('/', (req, res) => { res.send('hello world');});import express from 'express';
const app = express();
// respond with "hello world" when a GET request is made to the homepageapp.get('/', (req, res) => { res.send('hello world');});import express, { type Express, type Request, type Response } from 'express';
const app: Express = express();
// respond with "hello world" when a GET request is made to the homepageapp.get('/', (req: Request, res: Response) => { 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 routeapp.get('/', (req, res) => { res.send('GET request to the homepage');});
// POST method routeapp.post('/', (req, res) => { res.send('POST request to the homepage');});import { type Request, type Response } from 'express';
// GET method routeapp.get('/', (req: Request, res: Response) => { res.send('GET request to the homepage');});
// POST method routeapp.post('/', (req: Request, res: Response) => { 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});import { type Request, type Response, type NextFunction } from 'express';
app.all('/secret', (req: Request, res: Response, next: NextFunction) => { 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 Zeichenketten, Zeichenkettenmuster oder reguläre Ausdrücke sein.
Note
Express verwendet path-to-regexp um die Routenpfade zu finden; 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.
Routenpfade basierend auf Zeichenketten
Warning
Dieser Routenpfad wird den Anfragen an die Root-Route / entsprechen.
app.get('/', (req, res) => { res.send('root');});import { type Request, type Response } from 'express';
app.get('/', (req: Request, res: Response) => { res.send('root');});Dieser Routenpfad wird den Anfragen auf /about entsprechen.
app.get('/about', (req, res) => { res.send('about');});import { type Request, type Response } from 'express';
app.get('/about', (req: Request, res: Response) => { res.send('about');});Dieser Routenpfad entspricht den Anfragen zu /random.text.
app.get('/random.text', (req, res) => { res.send('random.text');});import { type Request, type Response } from 'express';
app.get('/random.text', (req: Request, res: Response) => { res.send('random.text');});Routenpfade basierend auf Stringmustern
Dieser Routenpfad stimmt mit acd und abcd überein.
app.get('/ab?cd', (req, res) => { res.send('ab?cd');});import { type Request, type Response } from 'express';
app.get('/ab?cd', (req: Request, res: Response) => { res.send('ab?cd');});Dieser Routenpfad stimmt mit abcd, abbcd, abbbcd usw. überein.
app.get('/ab+cd', (req, res) => { res.send('ab+cd');});import { type Request, type Response } from 'express';
app.get('/ab+cd', (req: Request, res: Response) => { res.send('ab+cd');});Dieser Routenpfad stimmt mit abcd, abxcd, abRANDOMcd, ab123cd usw. überein.
app.get('/ab*cd', (req, res) => { res.send('ab*cd');});import { type Request, type Response } from 'express';
app.get('/ab*cd', (req: Request, res: Response) => { res.send('ab*cd');});Dieser Routenpfad stimmt mit /abe und /abcde überein.
app.get('/ab(cd)?e', (req, res) => { res.send('ab(cd)?e');});import { type Request, type Response } from 'express';
app.get('/ab(cd)?e', (req: Request, res: Response) => { res.send('ab(cd)?e');});Routenpfade basierend auf regulären Ausdrücken
Zeichen wie $ müssen mit einem \ maskiert werden.
Dieser Routenpfad stimmt mit einem “a” darin überein.
app.get(/a/, (req, res) => { res.send('/a/');});import { type Request, type Response } from 'express';
app.get(/a/, (req: Request, res: Response) => { res.send('/a/');});Dieser Routenpfad stimmt mit ‘butterfly’ und ‘Drachenfly’ überein, aber nicht mit ‘butterflyman’, ‘Drachenflyman’ und so weiter.
app.get(/.*fly$/, (req, res) => { res.send('/.*fly$/');});import { type Request, type Response } from 'express';
app.get(/.*fly$/, (req: Request, res: Response) => { 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/:bookIdRequest URL: http://localhost:3000/users/34/books/8989req.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-:toRequest URL: http://localhost:3000/flights/LAX-SFOreq.params: { "from": "LAX", "to": "SFO" }Route path: /plantae/:genus.:speciesRequest URL: http://localhost:3000/plantae/Prunus.persicareq.params: { "genus": "Prunus", "species": "persica" }Um mehr Kontrolle über den exakten String zu haben, der mit einem Route-Parameter übereinstimmen kann, können Sie einen regulären Ausdruck in Klammern (()) anhängen:
Route path: /user/:userId(\d+)Request URL: http://localhost:3000/user/42req.params: {"userId": "42"}Weil der reguläre Ausdruck in der Regel Teil einer literalen Zeichenkette ist, Stellen Sie sicher, dass Sie \
Zeichen mit einem zusätzlichen Backslash maskieren, zum Beispiel \d+.
The * character in regular expressions is not interpreted in the usual way. Benutze {0,} anstelle von *.
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');});import { type Request, type Response, type NextFunction } from 'express';
app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { if (req.params.id === '0') { return next('route'); } res.send(`User ${req.params.id}`);});
app.get('/user/:id', (req: Request, res: Response) => { 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 Routenaufrufenext('route'), überspringt zur nächsten passenden/user/:idRoute
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!');});import { type Request, type Response } from 'express';
app.get('/example/a', (req: Request, res: Response) => { 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!'); });import { type Request, type Response, type NextFunction } from 'express';
app.get( '/example/b', (req: Request, res: Response, next: NextFunction) => { console.log('the response will be sent by the next function ...'); next(); }, (req: Request, res: Response) => { 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]);import { type Request, type Response, type NextFunction } from 'express';
const cb0 = function (req: Request, res: Response, next: NextFunction) { console.log('CB0'); next();};
const cb1 = function (req: Request, res: Response, next: NextFunction) { console.log('CB1'); next();};
const cb2 = function (req: Request, res: Response) { 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!'); });import { type Request, type Response, type NextFunction } from 'express';
const cb0 = function (req: Request, res: Response, next: NextFunction) { console.log('CB0'); next();};
const cb1 = function (req: Request, res: Response, next: NextFunction) { console.log('CB1'); next();};
app.get( '/example/d', [cb0, cb1], (req: Request, res: Response, next: NextFunction) => { console.log('the response will be sent by the next function ...'); next(); }, (req: Request, res: Response) => { 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.
| Methode | Beschreibung |
|---|---|
| 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'); });import { type Request, type Response } from 'express';
app .route('/book') .get((req: Request, res: Response) => { res.send('Get a random book'); }) .post((req: Request, res: Response) => { res.send('Add a book'); }) .put((req: Request, res: Response) => { 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:
const express = require('express');const router = express.Router();
// middleware that is specific to this routerconst timeLog = (req, res, next) => { console.log('Time: ', Date.now()); next();};router.use(timeLog);
// define the home page routerouter.get('/', (req, res) => { res.send('Birds home page');});// define the about routerouter.get('/about', (req, res) => { res.send('About birds');});
module.exports = router;import express from 'express';
const router = express.Router();
// middleware that is specific to this routerconst timeLog = (req, res, next) => { console.log('Time: ', Date.now()); next();};router.use(timeLog);
// define the home page routerouter.get('/', (req, res) => { res.send('Birds home page');});// define the about routerouter.get('/about', (req, res) => { res.send('About birds');});
export default router;import express, { type Request, type Response, type NextFunction } from 'express';
const router = express.Router();
// middleware that is specific to this routerconst timeLog = (req: Request, res: Response, next: NextFunction) => { console.log('Time: ', Date.now()); next();};router.use(timeLog);
// define the home page routerouter.get('/', (req: Request, res: Response) => { res.send('Birds home page');});// define the about routerouter.get('/about', (req: Request, res: Response) => { res.send('About birds');});
export default router;Laden Sie dann das Router-Modul in der App:
const birds = require('./birds');
// ...
app.use('/birds', birds);import birds from './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 });