Menu
CoddyTech

Una pagina che chiama l'API

Fa parte della sezione API REST del percorso Node.js di Coddy. Lezione 21 di 25.

Una pagina chiama la tua API con fetch. Una richiesta POST richiede tre opzioni: method, headers e body. Converti l’oggetto JavaScript in testo JSON per il body e indica che il testo è di tipo 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();

Il primo await riceve la risposta HTTP. Il secondo legge il suo body JSON. response.ok ti dice se il suo status rientra nell’intervallo dei valori che indicano un esito positivo. Uno status come 400 o 409 non rifiuta la promise di fetch; restituisce una risposta il cui ok è false. Il codice del modulo e dell’elenco è fornito: concentrati sull’invio della richiesta e sulla gestione del risultato.

La variabile message fornita fa riferimento al paragrafo dei messaggi della pagina. Imposta il suo textContent per visualizzare un testo oppure una stringa vuota per cancellarlo:

message.textContent = data.error.message;
// Cancellalo dopo l'esito positivo:
message.textContent = '';

La pagina e l’API condividono la stessa origine, quindi questa chiamata non richiede autorizzazioni CORS. FormData codifica un modulo in modo diverso da JSON; usa il testo JSON perché questa API utilizza express.json().

challenge icon

Sfida

Facile

La tua API non ha ancora un'interfaccia. Aggiungi una piccola pagina, servita dallo stesso server, con un modulo che aggiunge attività tramite l'API.

  1. In server.js, servi la cartella public con express.static, così che GET / restituisca public/index.html.
  2. In public/index.html, il listener per l'invio legge già il titolo. Fai in modo che invii la nuova attività all'API:
    • Usa la variabile title fornita, che contiene il testo inserito.
    • Inviala con fetch('/api/tasks', ...) come POST.
    • Il corpo è testo JSON creato con JSON.stringify, come {"title":"Water the plants"}.
    • La richiesta richiede l'intestazione 'Content-Type': 'application/json', nell'opzione headers di fetch; altrimenti express.json() non leggerà il corpo.
  3. Se la risposta è OK (la sua proprietà ok è true per qualsiasi stato da 200 a 299), svuota il modulo con form.reset(), svuota #message e chiama load() affinché l'elenco mostri la nuova attività.
  4. Altrimenti, il corpo della risposta ha il formato di errore visto in precedenza, per esempio:
    { "error": { "code": "conflict", "message": "A task with this title already exists" } }
    Mostra il suo message nel paragrafo #message.

I controlli eseguono lo script di questa pagina fornito con un piccolo modulo simulato e la vera API della lezione. Inviano un'attività e poi un duplicato, quindi controllano l'elenco, il modulo e il messaggio. Prova anche la pagina vera accanto all'editor.

Prova: invia GET /. La pagina si apre nella visualizzazione della pagina con le 3 attività iniziali. Digita "Water the plants" e premi Add: il campo di immissione si svuota e l'attività appare in fondo all'elenco. Digita di nuovo "Water the plants" e premi Add: l'elenco rimane invariato e sotto il modulo appare "A task with this title already exists".

Provalo tu

<!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>

Tutte le lezioni di API REST

Esercitati da solo: Playground Express