PUTによる置き換え
CoddyのNode.jsジャーニー「REST API」セクションの一部。レッスン 5/25。
編集フォームはタスク全体を、すべてのフィールドをまとめて送り返します。PUT は「リソースをこれで置き換える」という意味なので、本文にはすべての内容が含まれていなければなりません。
PATCH /api/invoices/7 { "paid": true } → paid changes
PUT /api/invoices/7 { "amount": 90, "paid": true } → invoice 7 replaced
PUT /api/invoices/7 { "paid": true } → 400: amount missingフィールドが欠けている PUT は 400 を返します。請求書の半分だけで置き換えると、金額が失われてしまうためです。id や作成時刻のようにサーバーが管理するフィールドは、本文からではなく、以前のバージョンから引き継ぎます。
const { id, issuedAt } = invoices[index];
invoices[index] = { id, amount, paid, issuedAt };チャレンジ
簡単編集フォームはタスク全体を一度に送り返します。クライアントから送られた内容でタスクを置き換える PUT ルートを追加しましょう。
routes/tasks.jsにPUT /api/tasks/:idを追加します。本文には、たとえば{ "title": "Book the big room", "done": true }のように、両方のフィールドを含める必要があります。- タスクの
titleとdoneを本文の値で置き換えます。保存済みのタスクにあるidとcreatedAtはそのまま使い、本文から取得してはいけません。ステータス 200 とタスク全体を返します:{ "id": 2, "title": "Book the big room", "done": true, "createdAt": "2026-03-03T10:30:00.000Z" } - 本文に
titleまたはdoneがない場合は、ステータス 400 と{ "error": "PUT needs every field: title and done" }を返し、何も変更しません。フィールドがないと判断するのは、本文にそのフィールド自体が存在しない場合だけです。"done": falseは有効な値です。 - その ID のタスクがない場合は、他のルートと同様に、ステータス 404 と
{ "error": "Task not found" }を返します。
試してみましょう: PUT /api/tasks/2 に { "title": "Book the big room", "done": true } を送ると、200 と上記のタスクが返ります。次に、PUT /api/tasks/2 に { "done": true } だけを送ると 400 が返り、GET /api/tasks/2 では引き続き "Book the big room" と表示されます。PUT /api/tasks/99 に両方のフィールドを送ると 404 が返ります。
自分で試してみよう
import { Router } from 'express';
import { nextId, tasks } from '../store.js';
const router = Router();
router.get('/', (req, res) => {
res.json(tasks);
});
router.get('/:id', (req, res) => {
const task = tasks.find((t) => t.id === Number(req.params.id));
if (!task) {
return res.status(404).json({ error: 'Task not found' });
}
res.json(task);
});
router.post('/', (req, res) => {
const { title } = req.body ?? {};
if (!title) {
return res.status(400).json({ error: 'title is required' });
}
const task = { id: nextId(), title, done: false, createdAt: new Date().toISOString() };
tasks.push(task);
res.status(201).location(`/api/tasks/${task.id}`).json(task);
});
router.patch('/:id', (req, res) => {
const task = tasks.find((t) => t.id === Number(req.params.id));
if (!task) {
return res.status(404).json({ error: 'Task not found' });
}
const { title, done } = req.body ?? {};
if (title !== undefined) task.title = title;
if (done !== undefined) task.done = done;
res.json(task);
});
router.delete('/:id', (req, res) => {
const index = tasks.findIndex((t) => t.id === Number(req.params.id));
if (index === -1) {
return res.status(404).json({ error: 'Task not found' });
}
tasks.splice(index, 1);
res.status(204).end();
});
export default router;
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
REST APIのすべてのレッスン
自分で練習してみよう: Expressプレイグラウンド