第 2 週 · API 設計與接上前端
REST 設計
用「資源 + 方法」設計留言板的網址,先畫地圖再寫程式。
正在打開這一關…
學習目標
- 說明 REST 在這門課裡指什麼
- 為留言板列出資源、路徑與方法
- 知道集合(很多筆)與單一資源(一筆)的網址差在哪
第 2 週要把第 1 週的櫃台,設計成別人看得懂的 API。我們用 REST 的一個實用版本:網址代表資源,HTTP 方法代表你要對它做的事。不追求名詞考試,追求留言板的地圖一眼看得懂。
用生活例子理解
資源是你能指著說「就是這個」的東西。留言是資源,使用者也是資源。動作不要塞進網址。
比較:
| 比較難懂 | 比較清楚 |
|---|---|
POST /api/createNewMessage |
POST /api/messages |
GET /api/getMessageById?id=3 |
GET /api/messages/3 |
POST /api/deleteMessage |
DELETE /api/messages/3 |
左邊把動詞寫進路徑,右邊讓方法當動詞,路徑當名詞。
生活比喻:圖書館的網址應該是「架號」,不是「請幫我做某件事」的句子。找第三本書,是走到 3 號位置(
GET /books/3),不是去一個叫doGetBook的櫃台再附紙條。
留言板這一週先做這些門:
| 方法 | 路徑 | 做什麼 | 成功時 |
|---|---|---|---|
GET |
/api/messages |
看全部留言 | 200 與陣列 |
POST |
/api/messages |
新增一則 | 201 與新的那則 |
DELETE |
/api/messages/3 |
刪掉 3 號 | 200 或 204 |
204 表示成功但沒有本文。刪除時兩種都常見。本課後面用 200 加一句 JSON,方便你在畫面上看到結果。
動手做
大約 20 分鐘。這一課先畫,不急著連資料庫。
- 拿紙或備忘錄,寫下「留言」這個資源有哪些欄位。至少要有:編號、作者、內容、建立時間。
- 照上表寫出三扇門。每扇門補一句:失敗時可能是哪個狀態碼。
- 再加一扇你自己想到的門,例如
GET /api/messages/3只看一則。寫下找不到時要回404。 - 檢查有沒有路徑裡出現動詞(get、create、delete)。有的話改成名詞路徑。
- 把這張表留著。明天開始照這張表寫程式。完整里程碑在
examples/02-guestbook-memory/,今天先不要把整份抄完。
案例
路由可以先寫成一張對照,再落到程式。程式只示範「看路徑的形狀」,明天才讀本文。
export default {
async fetch(request) {
const url = new URL(request.url);
const { pathname } = url;
// /api/messages/3 這種路徑,編號在最後一段。
const oneMessage = pathname.match(/^\/api\/messages\/(\d+)$/);
if (pathname === "/api/messages" && request.method === "GET") {
return Response.json([]);
}
if (pathname === "/api/messages" && request.method === "POST") {
return Response.json({ id: 1 }, { status: 201 });
}
if (oneMessage && request.method === "DELETE") {
return Response.json({ deleted: Number(oneMessage[1]) });
}
return Response.json({ error: "找不到這個路徑" }, { status: 404 });
},
};正則 /^\/api\/messages\/(\d+)$/ 的意思是:整個路徑都要符合,中間是數字。(\d+) 把數字抓出來,放在 oneMessage[1]。
常見錯誤
- 路徑設計成
/api/getMessages、/api/createMessage。功能做得出來,但方法與路徑各說各話,之後加修改、刪除會越長越亂。 - 用一個
/api/action再在 JSON 裡放action: "delete"。等於自己發明第二套路由。 - 編號用沒有檢查的字串拼進別的系統。今天先確認它是數字。
- 一次設計十種資源。留言板先把「留言」做穩。
自我檢查
- 為什麼
DELETE /api/messages/3比GET /api/delete?id=3清楚? - 集合與單筆的網址,你的表裡怎麼分?
- 新增成功你打算用
200還是201?兩者差在哪?