Menu
CoddyTech

Remplacer avec PUT

Fait partie de la section API REST du Journey Node.js de Coddy. Leçon 5 sur 25.

Un formulaire de modification renvoie la tâche entière, tous les champs à la fois. PUT signifie « remplacer la ressource par ceci », le corps doit donc être complet.

PATCH /api/invoices/7  { "paid": true }               → paid changes
PUT   /api/invoices/7  { "amount": 90, "paid": true } → invoice 7 replaced
PUT   /api/invoices/7  { "paid": true }               → 400: amount missing

Un PUT auquel il manque un champ renvoie 400 : remplacer une facture à moitié remplie ferait perdre le montant. Les champs appartenant au serveur, comme id et la date de création, proviennent de l’ancienne version, jamais du corps :

const { id, issuedAt } = invoices[index];
invoices[index] = { id, amount, paid, issuedAt };
challenge icon

Défi

Facile

Un formulaire de modification renvoie toute la tâche en une seule fois. Ajoute une route PUT qui remplace une tâche par les données envoyées par le client.

  1. Dans routes/tasks.js, ajoute PUT /api/tasks/:id. Son corps doit contenir les deux champs, par exemple { "title": "Book the big room", "done": true }.
  2. Remplace le title et le done de la tâche par les valeurs du corps. Conserve son id et son createdAt à partir de la tâche enregistrée ; ne les prends jamais dans le corps. Réponds avec le statut 200 et la tâche complète :
    { "id": 2, "title": "Book the big room", "done": true, "createdAt": "2026-03-03T10:30:00.000Z" }
  3. Si le corps ne contient pas title ou done, réponds avec le statut 400 et { "error": "PUT needs every field: title and done" }, sans rien modifier. Un champ est manquant uniquement s'il est totalement absent du corps : "done": false est une valeur valide.
  4. Si aucune tâche ne possède cet id, réponds avec le statut 404 et { "error": "Task not found" }, comme pour les autres routes.

Essaie : PUT /api/tasks/2 avec { "title": "Book the big room", "done": true } renvoie le statut 200 et la tâche ci-dessus. Ensuite, PUT /api/tasks/2 avec seulement { "done": true } renvoie le statut 400, et GET /api/tasks/2 affiche toujours "Book the big room". PUT /api/tasks/99 avec les deux champs renvoie le statut 404.

Essayez vous-même

import { Router } from 'express';
import { nextId, tasks } from '../store.js';

const router = Router();

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

router.get('/:id', (req, res) => {
    const task = tasks.find((t) => t.id === Number(req.params.id));
    if (!task) {
        return res.status(404).json({ error: 'Task not found' });
    }
    res.json(task);
});

router.post('/', (req, res) => {
    const { title } = req.body ?? {};
    if (!title) {
        return res.status(400).json({ error: 'title is required' });
    }
    const task = { id: nextId(), title, done: false, createdAt: new Date().toISOString() };
    tasks.push(task);
    res.status(201).location(`/api/tasks/${task.id}`).json(task);
});

router.patch('/:id', (req, res) => {
    const task = tasks.find((t) => t.id === Number(req.params.id));
    if (!task) {
        return res.status(404).json({ error: 'Task not found' });
    }
    const { title, done } = req.body ?? {};
    if (title !== undefined) task.title = title;
    if (done !== undefined) task.done = done;
    res.json(task);
});

router.delete('/:id', (req, res) => {
    const index = tasks.findIndex((t) => t.id === Number(req.params.id));
    if (index === -1) {
        return res.status(404).json({ error: 'Task not found' });
    }
    tasks.splice(index, 1);
    res.status(204).end();
});

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 API REST

Entraînez-vous par vous-même : Playground Express