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 テキストを使ってください。
チャレンジ
簡単あなたのAPIには、まだ画面がありません。同じサーバーから配信する小さなページを作り、そのフォームからAPIを通じてタスクを追加できるようにしましょう。
server.jsでexpress.staticを使ってpublicフォルダーを配信し、GET /でpublic/index.htmlが返されるようにします。public/index.htmlでは、送信イベントのリスナーがすでにタイトルを読み取っています。新しいタスクをAPIに送信するようにしましょう。- 入力テキストを含む、用意されている
title変数を使います。 fetch('/api/tasks', ...)を使ってPOSTとして送信します。- リクエストボディは、
JSON.stringifyで作成するJSONテキストです。たとえば{"title":"Water the plants"}のようになります。 - リクエストには、
fetchのheadersオプションで'Content-Type': 'application/json'ヘッダーが必要です。これがないと、express.json()はリクエストボディを読み取りません。
- 入力テキストを含む、用意されている
- レスポンスがOK(
okプロパティが200から299までのいずれかのステータスでtrue)の場合は、form.reset()でフォームをクリアし、#messageを空にして、load()を呼び出し、リストに新しいタスクを表示します。 - それ以外の場合、レスポンスボディは前に説明したエラー形式です。たとえば次のようになります。
{ "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プレイグラウンド