Traduire cette page

Outrepasser l'API Express

L’API Express se compose de différentes méthodes et propriétés sur les objets de requête et de réponse. Celles-ci sont héritées du prototype. Il y a deux points d’extension pour l’API Express :

  1. Les prototypes globaux à express.request et express.response.
  2. Prototypes spécifiques à l’application à app.request et app.response.

Modifier les prototypes globaux affectera toutes les applications Express chargées dans le même processus. Si vous le souhaitez, les modifications peuvent être apportées à l’application en modifiant uniquement les prototypes spécifiques à l’application après avoir créé une nouvelle application.

Méthodes

Vous pouvez remplacer la signature et le comportement des méthodes existantes avec vos propres méthodes en assignant une fonction personnalisée.

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);
};

L’implémentation ci-dessus modifie complètement la signature originale de res.sendStatus. Il accepte maintenant un code de statut, un type d’encodage, et le message à envoyer au client.

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.

La méthode surchargée peut maintenant être utilisée de cette manière:

res.sendStatus(404, 'application/json', '{"error":"resource not found"}');

Propriétés

Les propriétés de l’API Express sont soit :

  1. Propriétés assignées (ex: req.baseUrl, req.originalUrl)
  2. Défini comme getters (ex: req.secure, req.ip)

Puisque les propriétés de la catégorie 1 sont assignées dynamiquement sur les objets request et response dans le contexte du cycle de réponse de la requête courante, leur comportement ne peut pas être remplacé.

Les propriétés de la catégorie 2 peuvent être écrasées en utilisant l’API des extensions API Express.

Le code suivant réécrit comment la valeur de req.ip doit être dérivée. Maintenant, il retourne simplement la valeur de l’en-tête de la requête Client-IP.

Object.defineProperty(app.request, 'ip', {
configurable: true,
enumerable: true,
get() {
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:

types/express.d.ts
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.

Prototype

Afin de fournir l’API Express, les objets de requête/réponse passés à Express (via app(req, res), par exemple) doivent hériter de la même chaîne de prototypes. Par défaut, c’est http.IncomingRequest.prototype pour la requête et http.ServerResponse.prototype pour la réponse.

Sauf si nécessaire, il est recommandé de le faire uniquement au niveau de l’application, plutôt qu’au niveau mondial. Veillez également à ce que le prototype utilisé corresponde le plus près possible à la fonctionnalité des prototypes par défaut.

// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse
// for the given app reference
Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype);
Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype);