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 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
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');});import { type Request, type Response } from 'express';
app.get('/', (req: Request, res: Response) => { res.send('root');});
app.get('/about', (req: Request, res: Response) => { res.send('about');});
app.get('/random.text', (req: Request, res: Response) => { 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('/')}`);});import { type Request, type Response } from 'express';
app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => { // 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');});import { type Request, type Response } from 'express';
// Matches / , /foo , /foo/bar , etc.app.get('/{*splat}', (req: Request, res: Response) => { // 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');});import { type Request, type Response } from 'express';
app.get('/:file{.:ext}', (req: Request, res: Response) => { // 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$/');});import { type Request, type Response } from 'express';
// Matches any path containing "a"app.get(/a/, (req: Request, res: Response) => { res.send('/a/');});
// Matches paths ending with "fly" (butterfly, dragonfly, etc.)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" }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');});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 });