Menu
CoddyTech

Versionnement

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

Modifier la forme d’une réponse casse tous les clients qui l’utilisent déjà. Une version dans le chemin permet aux anciens et aux nouveaux clients de coexister : /api/v1/orders aujourd’hui, /api/v2/orders lorsque la forme change. Les chemins déplacés répondent par une redirection :

GET  /api/orders/5   →  308  Location: /api/v1/orders/5
POST /api/orders     →  308  Location: /api/v1/orders

Les codes 301 et 302 permettent aux clients de répéter une requête POST sous forme de requête GET, ce qui supprime le corps. 308 indique « répéter la même requête à cette adresse », méthode et corps compris. À l’intérieur d’un middleware monté, req.url ne contient plus le chemin de montage, tandis que req.originalUrl le conserve en entier :

// dans app.use('/api/orders', ...) pour GET /api/orders/5?full=1
req.url          // '/5?full=1'
req.originalUrl  // '/api/orders/5?full=1'
challenge icon

Défi

Facile
  • Montez le routeur des tâches sur /api/v1/tasks.
  • Chaque ancienne route /api/tasks répond avec une redirection 308 vers la même route sous /api/v1, avec la chaîne de requête incluse.
  • Les nouvelles tâches reçoivent Location: /api/v1/tasks/<id>.

Envoyez GET /api/tasks/2, POST /api/tasks avec { "title": "Order new chairs" }, puis GET /api/v1/tasks/2.

Essayez vous-même

import express from 'express';
import { sendError } from './errors.js';
import taskRoutes from './routes/tasks.js';

const BOARD_ORIGIN = 'https://board.example.com';

const app = express();
app.use(express.json());

// Permet aux pages de BOARD_ORIGIN d’appeler cette API depuis le navigateur.
app.use((req, res, next) => {
    res.set('Access-Control-Allow-Origin', BOARD_ORIGIN);
    res.set('Access-Control-Allow-Credentials', 'true');
    if (req.method === 'OPTIONS') {
        res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE');
        res.set('Access-Control-Allow-Headers', 'Content-Type');
        return res.status(204).end();
    }
    next();
});

app.use(express.static('public'));

app.use('/api/tasks', taskRoutes);

// Les erreurs provenant des routes arrivent ici. Un corps qui n’est pas du JSON valide est une
// erreur du client (400) ; toute autre erreur vient de nous (500).
app.use((err, req, res, next) => {
    if (err.type === 'entity.parse.failed') {
        return sendError(res, 400, 'invalid_json', 'The body is not valid JSON');
    }
    console.error(err);
    sendError(res, 500, 'server_error', 'Something went wrong');
});

app.listen(3000, () => {
    console.log('Task tracker API on port 3000');
});

Toutes les leçons de API REST