Menu
CoddyTech

Une page qui appelle l’API

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

Une page appelle votre API avec fetch. Un POST nécessite trois options : method, headers et body. Convertissez l’objet JavaScript en texte JSON pour le corps, et indiquez que ce texte est de type application/json.

const response = await fetch('/api/books', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({title: title}),
});
const data = await response.json();

Le premier await reçoit la réponse HTTP. Le second lit son corps JSON. response.ok vous indique si son statut se situe dans la plage de réussite. Un statut tel que 400 ou 409 ne rejette pas la promesse de fetch ; il renvoie une réponse dont la valeur ok est false. Le code du formulaire et de la liste est fourni ; concentrez-vous sur l’envoi de la requête et le traitement de son résultat.

La variable message fournie fait référence au paragraphe de message de la page. Définissez son textContent avec le texte à afficher, ou avec une chaîne vide pour l’effacer :

message.textContent = data.error.message;
// Efface-le après une opération réussie :
message.textContent = '';

La page et l’API partagent la même origine, cet appel ne nécessite donc aucune autorisation CORS. FormData encode un formulaire différemment du JSON ; utilisez du texte JSON, car cette API utilise express.json().

challenge icon

Défi

Facile

Votre API n’a pas encore d’interface. Ajoutez-lui une petite page, servie par le même serveur, dont le formulaire ajoute des tâches via l’API.

  1. Dans server.js, servez le dossier public avec express.static, afin que GET / renvoie public/index.html.
  2. Dans public/index.html, l’écouteur de soumission lit déjà le titre. Faites-lui envoyer la nouvelle tâche à l’API :
    • Utilisez la variable title fournie, qui contient le texte saisi.
    • Envoyez-le avec fetch('/api/tasks', ...) comme requête POST.
    • Le corps est du texte JSON créé avec JSON.stringify, comme {"title":"Water the plants"}.
    • La requête doit inclure l’en-tête 'Content-Type': 'application/json', dans l’option headers de fetch, sinon express.json() ne lira pas le corps.
  3. Si la réponse est OK (sa propriété ok vaut true pour tout statut compris entre 200 et 299), videz le formulaire avec form.reset(), videz #message et appelez load() afin que la liste affiche la nouvelle tâche.
  4. Sinon, le corps de la réponse a la structure d’erreur vue précédemment, par exemple :
    { "error": { "code": "conflict", "message": "A task with this title already exists" } }
    Affichez son message dans le paragraphe #message.

Les vérifications exécutent le script fourni pour cette page avec un petit formulaire simulé et l’API réelle de la leçon. Elles soumettent une tâche et un doublon, puis inspectent la liste, le formulaire et le message. Essayez aussi la page réelle à côté de l’éditeur.

À essayer : envoyez GET /. La page s’ouvre dans la vue de page avec les 3 tâches initiales. Saisissez "Water the plants" et cliquez sur Add : le champ se vide et la tâche apparaît en bas de la liste. Saisissez de nouveau "Water the plants" et cliquez sur Add : la liste reste inchangée et "A task with this title already exists" apparaît sous le formulaire.

Essayez vous-même

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Tasks</title>
</head>
<body>
    <h1>Tasks</h1>
    <ul id="list"></ul>
    <form id="add">
        <input name="title" placeholder="New task" required>
        <button>Add</button>
    </form>
    <p id="message"></p>
    <script>
        const list = document.querySelector('#list');
        const form = document.querySelector('#add');
        const message = document.querySelector('#message');

        async function load() {
            const response = await fetch('/api/tasks?limit=50');
            const page = await response.json();
            list.replaceChildren(...page.items.map((task) => {
                const item = document.createElement('li');
                item.textContent = (task.done ? '[x] ' : '[ ] ') + task.title;
                return item;
            }));
        }

        form.addEventListener('submit', async (event) => {
            event.preventDefault();
            const title = form.elements.title.value;
            // Send the title to POST /api/tasks as JSON. On success clear
            // the form and load() again; on an error show its message.
        });

        load();
    </script>
</body>
</html>

Toutes les leçons de API REST

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