Menu
CoddyTech

APIを呼び出すページ

CoddyのNode.jsジャーニー「REST API」セクションの一部。レッスン 21/25。

ページは fetch を使って API を呼び出します。POST には3つのオプションが必要です。method、headers、body です。JavaScript オブジェクトを JSON テキストに変換して body に指定し、そのテキストを 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();

最初の await は HTTP レスポンスを受け取ります。2つ目はその JSON ボディを読み取ります。response.ok は、ステータスが成功を示す範囲内かどうかを知らせます。400 や 409 などのステータスでも fetch の Promise は reject されません。ok が false のレスポンスが返されます。フォームとリストのコードは用意されています。リクエストの送信と、その結果の処理に集中してください。

用意されている message 変数は、ページのメッセージ段落を参照します。表示するテキストを textContent に設定するか、メッセージを消すには空の文字列を設定します。

message.textContent = data.error.message;
// 成功したらクリアする:
message.textContent = '';

ページと API は同じオリジンを共有しているため、この呼び出しに CORS の許可は必要ありません。FormData はフォームを JSON とは異なる形式でエンコードします。この API は express.json() を使用するため、JSON テキストを使ってください。

challenge icon

チャレンジ

簡単

あなたのAPIには、まだ画面がありません。同じサーバーから配信する小さなページを作り、そのフォームからAPIを通じてタスクを追加できるようにしましょう。

  1. server.jsでexpress.staticを使ってpublicフォルダーを配信し、GET /でpublic/index.htmlが返されるようにします。
  2. public/index.htmlでは、送信イベントのリスナーがすでにタイトルを読み取っています。新しいタスクをAPIに送信するようにしましょう。
    • 入力テキストを含む、用意されているtitle変数を使います。
    • fetch('/api/tasks', ...)を使ってPOSTとして送信します。
    • リクエストボディは、JSON.stringifyで作成するJSONテキストです。たとえば{"title":"Water the plants"}のようになります。
    • リクエストには、fetchのheadersオプションで'Content-Type': 'application/json'ヘッダーが必要です。これがないと、express.json()はリクエストボディを読み取りません。
  3. レスポンスがOK(okプロパティが200から299までのいずれかのステータスでtrue)の場合は、form.reset()でフォームをクリアし、#messageを空にして、load()を呼び出し、リストに新しいタスクを表示します。
  4. それ以外の場合、レスポンスボディは前に説明したエラー形式です。たとえば次のようになります。
    { "error": { "code": "conflict", "message": "A task with this title already exists" } }
    messageを#messageの段落に表示します。

チェックでは、この用意されたページのスクリプトを、小さなシミュレーション用フォームと実際のレッスンAPIを使って実行します。タスクと重複するタスクを送信し、リスト、フォーム、メッセージを確認します。エディターの横で実際のページも試してみましょう。

試してみましょう: GET /を送信します。ページビューにページが開き、最初の3つのタスクが表示されます。「Water the plants」と入力してAddを押すと、入力欄が空になり、タスクがリストの一番下に表示されます。もう一度「Water the plants」と入力してAddを押すと、リストは変わらず、フォームの下に「A task with this title already exists」と表示されます。

自分で試してみよう

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

REST APIのすべてのレッスン

自分で練習してみよう: Expressプレイグラウンド