Routage Node.js

Dans Node.js, le routage est un élément clé du traitement des requêtes HTTP. Il détermine comment distribuer les requêtes en fonction des différentes URL et méthodes HTTP (telles que GET, POST, PUT, DELETE, etc.).

Le routage est couramment utilisé pour créer des applications web, en particulier des API RESTful.

Node.js lui-même ne dispose pas de mécanismes de routage intégrés, mais ils peuvent être mis en œuvre via des bibliothèques middleware (telles qu'Express).

Le routage implique généralement les aspects suivants :

  • Correspondance d'URL: Faire correspondre les règles de routage en fonction de l'URL demandée.
  • Correspondance de méthode HTTP: Faire correspondre les règles de routage en fonction de la méthode HTTP demandée (GET, POST, PUT, DELETE, etc.).
  • Traitement des requêtes: Une fois qu'une règle de routage correspondante est trouvée, la fonction gestionnaire correspondante est appelée pour traiter la requête.

Dans Node.js, nous pouvons créer une route simple via le module http, comme dans l'exemple suivant :

Exemple

const http = require('http');

// Créer un serveur et définir des routes
const server = http.createServer((req, res) => {
  const { url, method } = req;

  if (url === '/' && method === 'GET') {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Home Page');
  } else if (url === '/about' && method === 'GET') {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('About Page');
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('404 Non trouvé');
  }
});

server.listen(3000, () => {
  console.log('Le serveur est en cours d'exécution sur http://localhost:3000');
});

Accès navigateurhttp://localhost:3000S'affiche comme suit :

Accès navigateurhttp://localhost:3000/aboutS'affiche comme suit :

Si d'autres adresses URL sont accédées, il affichera directement404 Introuvable。

Pour plus de requêtes HTTP, consultez :Tutoriel HTTP。


Paramètres de requête

Une URL complètehttp://localhost:8888/start?foo=bar&hello=worldcontient l'hôte, le chemin et la chaîne de requête.

Pour analyser ces données, nous pouvons utiliser l'objetURLet le modulequerystring.

const myUrl = new URL("http://localhost:8888/start?foo=bar&hello=world");

// 提取路径名
console.log(myUrl.pathname); // 输出: /start

// 提取查询参数
console.log(myUrl.searchParams.get("foo"));   // 输出: bar
console.log(myUrl.searchParams.get("hello")); // 输出: world
myUrl.pathname
          |
          |
        -----
http://localhost:8888/start?foo=bar&hello=world
                                ---       -----
                                 |          |
                                 |          |
           myUrl.searchParams.get("foo")    |
                                            |
                                     myUrl.searchParams.get("hello")

Bien sûr, nous pouvons également utiliser le module querystring pour analyser les paramètres dans le corps de la requête POST. Cela sera présenté plus tard dansRequêtes GET/POST Node.js.

Toutes les données de requête dont nous avons besoin seront contenues dans l'objet request, qui est passé comme premier paramètre à la fonction de rappel onRequest().

Ajoutons maintenant un peu de logique à la fonction onRequest() du module http pour déterminer le chemin URL demandé par le navigateur :

Code du fichier server.js :

var http = require("http"); var url = require("url"); function start() { function onRequest(request, response) { //Utilisez le constructeur URL pour analyser le chemin de la requête const pathname = new URL(request.url, `http://${request.headers.host}`).pathname; console.log(`Requête pour ${pathname} reçue.`); //Afficher le chemin de la requête //Définir l'en-tête de la réponse et le contenu de la réponse response.writeHead(200, { "Content-Type": "text/plain" }); //Définir le code d'état et le type de contenu response.write("Bonjour le monde"); //Envoyer le contenu de la réponse au client response.end(); //Terminer la réponse } //Créer un serveur et écouter sur le port spécifié http.createServer(onRequest).listen(8888); console.log("Le serveur a démarré."); //Afficher le message de démarrage du serveur } //Exporter la fonction start pour utilisation par d'autres modules module.exports.start = start;

D'accord, notre application peut maintenant distinguer différentes requêtes en fonction du chemin d'URL demandé - cela nous permet d'utiliser le routage (pas encore complet) pour associer les requêtes à des gestionnaires en fonction du chemin d'URL.

Dans l'application que nous allons construire, cela signifie que les requêtes provenant de /start et /upload peuvent être traitées avec un code différent. Plus tard, nous verrons comment ces éléments s'articulent.

Maintenant, nous pouvons écrire la route. Créez un fichier nommérouter.jset ajoutez le contenu suivant :

Code du fichier router.js :

function route(pathname) { console.log("Sur le point d'acheminer une requête pour " + pathname); } //Exporter la fonction route exports.route = route;

router.js gère la logique de routage, définit et exporte la fonction route, qui est utilisée pour gérer différents chemins lorsque le serveur reçoit une requête.

Notre serveur devrait connaître la route et l'utiliser efficacement. Nous pourrions bien sûr coder cette dépendance en dur dans le serveur, mais l'expérience de programmation dans d'autres langages nous dit que ce serait très douloureux, nous allons donc utiliser l'injection de dépendances pour ajouter le module de routage de manière faiblement couplée.

Tout d'abord, étendons la fonction start() du serveur afin que la fonction route puisse être passée en paramètre.server.jsLe code du fichier est le suivant :

Code du fichier server.js :

// server.js const http = require("http"); //Importer le module http de Node.js pour créer un serveur const { URL } = require("url"); //Importer le constructeur URL depuis le module url //Définir et exporter la fonction start pour démarrer le serveur function start(route) { //Définir la fonction onRequest pour gérer chaque requête function onRequest(request, response) { //Utiliser le constructeur URL pour analyser le chemin de la requête const pathname = new URL(request.url, `http://${request.headers.host}`).pathname; console.log(`Requête pour ${pathname} received.`); //Afficher le chemin de la requête route(pathname); //Appeler la fonction route pour gérer le chemin //Définir l'en-tête de réponse et le contenu de la réponse response.writeHead(200, { "Content-Type": "text/plain" }); response.write("Hello World"); response.end(); } //Créer un serveur et écouter sur le port spécifié http.createServer(onRequest).listen(8888); console.log("Le serveur a démarré."); } //Exporter la fonction start pour qu'elle soit utilisée par d'autres modules module.exports.start = start;

server.js définit la logique de démarrage du serveur et appelle la fonction route lorsqu'une requête est reçue.

En même temps, nous étendrons index.js en conséquence afin que la fonction route puisse être injectée dans le serveur :

Code du fichier index.js :

var server = require("./server"); var router = require("./router"); server.start(router.route);

index.js est le fichier d'entrée du programme, chargé de démarrer le serveur et de transmettre le module de routage au module serveur.

Maintenant, démarrez l'application (node index.js, souvenez-vous toujours de cette ligne de commande), puis faites une requête vers une URL. Vous verrez l'application afficher les informations correspondantes, ce qui montre que notre serveur HTTP utilise déjà le module de routage et transmettra le chemin de la requête à la route :

$ node index.js
Server has started.

Accédez à l'URL suivante dans le navigateurhttp://localhost:8888/, et le serveur devrait afficher sur la console le message lié à la route pour ce chemin et renvoyer une réponse "Hello World" :

Le terminal du backend affichera les informations d'accès :

Request for / received.
About to route a request for /
Request for /favicon.ico received.
About to route a request for /favicon.ico

Routage avec Express

Express est un framework Node.js populaire qui offre de puissantes capacités de routage.

Pour en savoir plus sur Express, consultez :Node.js Express Framework。

Installation d'Express

Tout d'abord, assurez-vous d'avoir installé Express. Si ce n'est pas le cas, vous pouvez utiliser npm pour l'installer :

npm install express

Routage de base

Voici une application Express simple qui montre comment mettre en place un routage de base :

Exemple

const express = require('express');
const app = express();
const port = 3000;

// Définir une route GET
app.get('/', (req, res) => {
    res.send('Hello, World!');
});

// Définir une route POST
app.post('/submit', (req, res) => {
    res.send('Form submitted!');
});

// Démarrer le serveur
app.listen(port, () => {
    console.log(`Server is running on http://localhost:${port}`);
});

Routage dynamique

Le routage dynamique vous permet d'utiliser des URL paramétrées.

Par exemple, vous pouvez définir une route pour gérer/users/:id, où:idest un paramètre dynamique.

app.get('/users/:id', (req, res) => {
    const userId = req.params.id;
    res.send(`User ID: ${userId}`);
});

Paramètres de route

Express vous permet d'extraire des paramètres de l'URL et d'y accéder via l'objet req.params.

Exemple

app.get('/users/:id', (req, res) => {
    const userId = req.params.id;
    res.send(`ID utilisateur: ${userId}`);
});

app.get('/search/:query', (req, res) => {
    const query = req.params.query;
    res.send(`Requête de recherche: ${query}`);
});

Paramètres de requête

Les paramètres de requête sont des paires clé-valeur dans l'URL, généralement utilisés pour transmettre des informations supplémentaires. Vous pouvez accéder aux paramètres de requête via l'objet req.query.

app.get('/search', (req, res) => {
    const query = req.query.q;
    res.send(`Search query: ${query}`);
});

Middleware de route

Les middlewares de route sont des fonctions exécutées avant ou après le traitement d'une requête. Vous pouvez utiliser des middlewares pour gérer des tâches telles que l'authentification, la journalisation, etc.

// 日志记录中间件
const logger = (req, res, next) => {
    console.log(`Request Type: ${req.method} ${req.url}`);
    next();
};

// 使用中间件
app.use(logger);

app.get('/', (req, res) => {
    res.send('Hello, World!');
});

Regroupement de routes

Pour mieux organiser votre code, vous pouvez utiliser le regroupement de routes. Express fournit l'objet express.Router, qui peut être utilisé pour créer des gestionnaires de routes modulaires et montables.

Exemple

const express = require('express');
const app = express();
const port = 3000;

// Créer une instance de routeur
const userRouter = express.Router();

// Définir les routes liées aux utilisateurs
userRouter.get('/', (req, res) => {
    res.send('Liste des utilisateurs');
});

userRouter.get('/:id', (req, res) => {
    const userId = req.params.id;
    res.send(`ID utilisateur: ${userId}`);
});

// Monter le routeur utilisateur
app.use('/users', userRouter);

// Démarrer le serveur
app.listen(port, () => {
    console.log(`Server is running on http://localhost:${port}`);
});

Techniques de routage avancées

1. Gestion des erreurs :Vous pouvez définir un middleware de gestion des erreurs pour intercepter et gérer les erreurs dans les routes.

app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send('Something broke!');
});

2. Priorité des routes :L'ordre dans lequel les routes sont définies détermine leur priorité ; les routes définies en premier seront mises en correspondance en premier.

3. Restrictions d'accès aux routes :Vous pouvez utiliser un middleware pour restreindre l'accès à certaines routes, par exemple, en autorisant uniquement les utilisateurs authentifiés.

Exemple

const authMiddleware = (req, res, next) => {
    if (req.headers.authorization) {
        next();
    } else {
        res.status(401).send('Unauthorized');
    }
};

app.get('/admin', authMiddleware, (req, res) => {
    res.send('Admin page');
});
Autres extensions