Menu
CoddyTech

Routes asynchrones

Fait partie de la section Les bases d’Express du Journey Node.js de Coddy. Leçon 18 sur 20.

Un tableau disparaît lorsque le serveur redémarre. Un fichier conserve les données.

import { readFile } from 'node:fs/promises';

app.get('/api/forecast', async (req, res) => {
    const text = await readFile('data/forecast.json', 'utf8');
    res.json(JSON.parse(text));
});

Une route peut être une fonction async qui attend avec await, ici readFile de node:fs/promises. Express 5 surveille la promesse renvoyée par la route : si elle est rejetée, parce que le fichier est introuvable ou que son JSON est invalide, l’erreur est transmise à votre gestionnaire d’erreurs, comme avec une exception.

Sans await, vous obtenez une promesse au lieu des données, et res.json(promise) envoie {}. Le nouveau fichier data/recipes.json contient les quatre recettes.

challenge icon

Défi

Facile
  • Chaque route de routes/recipes.js lit les recettes depuis data/recipes.json à chaque requête.
  • POST enregistre la nouvelle liste avec writeFile.

Ajoute une recette, puis envoie GET /api/recipes, GET /api/recipes/5 et GET /api/recipes/99.

Essayez vous-même

import express from 'express';
import { recipes } from '../data.js';

const router = express.Router();

// Chaque tag, une seule fois, par ordre alphabétique.
router.get('/tags', (req, res) => {
    const tags = new Set(recipes.flatMap((recipe) => recipe.tags));
    res.json([...tags].sort());
});

router.get('/', (req, res) => {
    res.json(recipes);
});

router.get('/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).json({ error: 'No such recipe' });
        return;
    }
    res.json(recipe);
});

router.post('/', (req, res) => {
    const { title, tags } = req.body;
    if (!title) {
        res.status(400).json({ error: 'A recipe needs a title' });
        return;
    }
    const recipe = { id: recipes.length + 1, title, tags: tags ?? [] };
    recipes.push(recipe);
    res.status(201).json(recipe);
});

router.get('/:id/scale', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).json({ error: 'No such recipe' });
        return;
    }
    const by = Number(req.query.by);
    if (!Number.isFinite(by) || by <= 0) {
        res.status(400).json({ error: 'Scale by a positive number' });
        return;
    }
    if (!recipe.servings) {
        throw new Error(`Recipe ${recipe.id} has no servings`);
    }
    res.json({ title: recipe.title, servings: recipe.servings * by });
});

export default router;
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Les bases d’Express