Überschreiben der Express-API
Die Express API besteht aus verschiedenen Methoden und Eigenschaften auf den Anfrage- und Antwort-Objekten. Diese werden vom Prototyp geerbt. Es gibt zwei Erweiterungspunkte für die Express API:
- Die globalen Prototypen unter
express.requestundexpress.response. - App-spezifische Prototypen bei
app.requestundapp.response.
Das Ändern der globalen Prototypen wirkt sich auf alle geladenen Express-Apps im selben Prozess aus. Wenn gewünscht, können Änderungen app-spezifisch gemacht werden, indem nur app-spezifische Prototypen nach dem Erstellen einer neuen App geändert werden.
Methoden
Sie können die Signatur und das Verhalten bestehender Methoden mit eigenen überschreiben, indem Sie eine benutzerdefinierte Funktion zuweisen.
Following is an example of overriding the behavior of res.sendStatus.
app.response.sendStatus = function (statusCode, type, message) { // code is intentionally kept simple for demonstration purpose return this.contentType(type).status(statusCode).send(message);};import { type Response } from 'express';
// Broaden the type of sendStatus so call sites accept the new arguments.declare module 'express-serve-static-core' { interface Response { sendStatus(statusCode: number, type: string, message: string): this; }}
app.response.sendStatus = function ( this: Response, statusCode: number, type: string, message: string) { // code is intentionally kept simple for demonstration purpose return this.contentType(type).status(statusCode).send(message);} as Response['sendStatus'];Die obige Implementierung ändert die ursprüngliche Signatur von res.sendStatus. Es akzeptiert nun einen Statuscode, Kodierungstyp und die Nachricht, die an den Client gesendet werden soll.
In TypeScript, augmenting express-serve-static-core adds the new overload to the Response type so call sites such as res.sendStatus(404, 'application/json', body) type-check. The assignment is cast with as Response['sendStatus'] because replacing a method with a different signature cannot be checked against the original declaration.
Die überschriebene Methode kann nun auf diese Weise verwendet werden:
res.sendStatus(404, 'application/json', '{"error":"resource not found"}');Eigenschaften
Eigenschaften in der Express-API sind entweder:
- Zugewiesene Eigenschaften (z.B.
req.baseUrl,req.originalUrl) - Definiert als Getters (z. B.:
req.secure,req.ip)
Da Eigenschaften in Kategorie 1 dynamisch auf den request und response Objekten im Kontext des aktuellen Request-Antwort-Zyklus zugewiesen werden ihr Verhalten kann nicht überschrieben werden.
Eigenschaften der Kategorie 2 können mit der Express API Extensions API überschrieben werden.
Der folgende Code schreibt neu wie der Wert von req.ip abgeleitet wird. Jetzt gibt es einfach den Wert des Client-IP Request-Headers zurück.
Object.defineProperty(app.request, 'ip', { configurable: true, enumerable: true, get() { return this.get('Client-IP'); },});import { type Request } from 'express';
Object.defineProperty(app.request, 'ip', { configurable: true, enumerable: true, get(this: Request) { return this.get('Client-IP'); },});Extending the API in TypeScript
The sections above override members that Express already provides. To add your own properties or
methods to the request or response, describe them to TypeScript with
declaration merging on the
Express namespace. Put the augmentation in a .d.ts file that is part of your project. No
tsconfig.json change is needed unless a custom include does not cover its location.
For example, an authentication middleware may attach a user to the request, and you might add a
sendError helper to the response:
interface User { id: string; name: string;}
declare global { namespace Express { interface Request { user?: User; } interface Response { sendError(status: number, message: string): this; } }}
export {};The additions are now known throughout the application:
import { type Request, type Response, type NextFunction } from 'express';
app.use((req: Request, res: Response, next: NextFunction) => { req.user = { id: '1', name: 'Tobi' }; next();});
app.response.sendError = function (this: Response, status: number, message: string) { return this.status(status).json({ error: message });};
app.get('/', (req: Request, res: Response) => { if (!req.user) { res.sendError(401, 'unauthorized'); return; } res.send(req.user.name);});Declare custom request properties as optional (user?). The type applies to every request, but
TypeScript cannot know which middleware ran before a given handler, so a required property would be a
false guarantee. Check for the value (as with if (!req.user) above) before relying on it.
Adding a new method needs no cast, unlike overriding an existing method with a different signature, because the method did not previously exist on the type.
Prototyp
Um die Express API zur Verfügung zu stellen, werden die Anfrage/Antwort-Objekte an Express weitergegeben (via app(req, res), zum Beispiel, müssen von der gleichen Prototypenkette zu erben. Standardmäßig ist dies http.IncomingRequest.prototype für die Anfrage und http.ServerResponse.prototype für die Antwort.
Wenn nötig, wird empfohlen, dass dies nur auf der Anwendungsebene und nicht auf globaler Ebene geschieht. Achten Sie auch darauf, dass der verwendete Prototyp die Funktionalität so nah wie möglich an die Standard-Prototypen anpasst.
// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse// for the given app referenceObject.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype);Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype);