Routage avec Express.js
Les routes dynamiques
On a vu qu'on pouvait ajouter des paramètres à l'url en utilisant le caractère ? suivi du nom du paramètre et de sa valeur.
http://localhost:3000/professeurs?code=1
On peut aussi ajouter la valeur du paramètre directement dans l'url sans le nommer, c'est ce qu'on appelle une route dynamique.
http://localhost:3000/professeurs/1
Dans cet exemple on pourra récupérer la valeur 1 dans l'url comme étant un paramètre. Les deux méthodes sont utilisées mais la deuxième fait clairement la distinction entre l'identité de la ressource et les paramètres comme le tri et la pagination.
Dans le code, quand on déclare la route on ajoute le nom du paramètre précédé du caractère : (deux points). Ensuite le paramètre sera stocké dans l'objet req.params et portera le nom défini dans la route.
app.get('/professeurs/:code', (req, res) => {
const code = req.params.code;
res.send(`Vous avez demandé le professeur avec le code ${code}`);
});
Si on veut utiliser deux paramètres de cette façon, on doit les séparer par un /.
http://localhost:3000/professeurs/1/cours/2
app.get('/professeurs/:code_professeur/cours/:code_cours', (req, res) => {
const params = req.params;
res.send(`Vous avez demandé le cours ${params.code_cours} du professeur avec le code ${params.code_professeur}`);
});
Danger
Faites attention à l'ordre des routes dynamiques si des routes peuvent être confondues.
Par exemple j'ai ces deux routes:
app.get('/professeurs/:code_professeur/cours/:code_cours', (req, res) => {
const params = req.params;
res.send(`Vous avez demandé le cours ${params.code_cours} du professeur avec le code ${params.code_professeur}`);
});
app.get('/professeurs/:code_professeur', (req, res) => {
const code = req.params.code;
res.send(`Vous avez demandé le professeur avec le code ${code}`);
});
Dans cet ordre là, tout va bien. Si je fais la requête /professeurs/1/cours/2 je vais accéder à la première route et obtenir le 2e cours du professeur avec le code 1.
Par contre si j'inverse les routes:
app.get('/professeurs/:code_professeur', (req, res) => {
const code = req.params.code;
res.send(`Vous avez demandé le professeur avec le code ${code}`);
});
app.get('/professeurs/:code_professeur/cours/:code_cours', (req, res) => {
const params = req.params;
res.send(`Vous avez demandé le cours ${params.code_cours} du professeur avec le code ${params.code_professeur}`);
});
on ne pourra jamais accéder à la route /professeurs/1/cours/2 car la partie /professeurs/1 du chemin sera toujours attrapée par la première route, et le reste sera ignoré.
À
Toujours mettre les routes les plus spécifiques en premier.
Le routage
Le module Router permet de regrouper plusieurs routes similaires. C'est une bonne pratique pour maintenir un code clair et consistant qu'on pourra faire évoluer facilement.
Reprenons l'exemple des deux routes professeurs plus haut. On doit premièrement créer un fichier qui va contenir toutes ces routes similaires. Ensuite dans ce fichier on importe le module Express et crée un objet Router.
Au lieu de définir les routes avec app on va utiliser l'objet router que l'on vient de créer. Finalement à la fin du fichier on va exporter le module pour pouvoir l'utiliser dans notre fichier index.js
Vous avez remarqué que le segment /professeurs n'apparaît plus dans les routes? Ce segment de la route va être géré dans le fichier index.js. La seule modification à faire est d'ajouter notre router à l'application express en utilisant la méthode app.use() puisqu'il se comporte comme un middleware.
Toutes les routes qui débutent par /api/professeurs seront dirigées vers le fichier ./professeurs.route.js (L'ajout de api dans la route est purement esthétique). Donc maintenant quand le serveur recevra par exemple la route /api/professeurs/1/cours/2 il va diriger la requète dans le fichier professeurs.route.js pour trouver quoi faire avec le reste de la route: /1/cours/2.
Avec Router on peut organiser notre projet de plusieurs façons. Nous verrons dans la prochaine section des exemples de bonnes structures à adopter pour nos APIs.
Manuel