你打開一個待辦事項 App,看見今天的任務;按下新增,清單多一筆;改掉其中一筆內容,再把另一筆刪掉。畫面上只是幾個按鈕,但前端送到伺服器的 request 可能分別是 GET、POST、PUT 或 DELETE。它們不是「工程師習慣這樣命名」而已,而是 HTTP 本身定義的 request methods,用來告訴伺服器:這次 request 想對某個資源做什麼。
REST API 可以先理解成:依照 REST 架構風格設計,讓 client 透過統一介面操作 resource 的 API。 在 Web 上,這套介面通常建立在 HTTP 之上,所以常見做法是用 URL 指向 resource,再用 GET、POST、PUT、DELETE 等 HTTP method 表達操作。
先記一句:REST 不是一個網路協定,也不是「回傳 JSON 的 API」的別名。它是一種架構風格;HTTP 則是 RESTful Web API 最常使用的協定。
REST 真正在意的,不是網址長得漂不漂亮
REST 全名是 Representational State Transfer。Roy Fielding 在 2000 年的博士論文中,用它描述一套適合分散式超媒體系統的架構風格。REST 由多個 constraint 組成,其中最重要的概念之一是 uniform interface:不同 client 不需要為每個服務重新發明一套完全不同的互動方式,而是透過一致的介面和 resource 互動。
所以 REST 不只是「URL 要用名詞」。如果一個 API 長得像 /users/42,卻把所有操作都塞進同一個 POST,再自己發明 action=read、action=delete,它雖然還是能工作,但其實沒有充分利用 HTTP 已經提供的操作語意。
實務上「REST API」這個詞也常被用得比較寬鬆。很多被叫做 RESTful 的 API,會做到 resource-oriented URL、HTTP methods、status codes、stateless request,卻沒有完整實作 REST 原始論文裡 uniform interface 的所有細節,例如 hypermedia。知道這個差異很重要:不要把業界常見的「REST-like HTTP API」和嚴格的 REST 定義完全畫上等號。
Resource 是你在操作的「東西」
REST 裡很常看到 resource。它不是只能代表資料庫的一列,而是服務願意讓 client 識別和操作的概念,例如使用者、文章、訂單、留言、課程或待辦事項。URL 常用來識別這些 resource:
/tasks
/tasks/42
/users/7
/articles/2026-rest-api
/tasks 可以代表「任務集合」,/tasks/42 則代表其中一個特定任務。Client 真正收到的通常不是 resource 本體,而是它的某種 representation,例如 JSON:
{
"id": 42,
"title": "整理 API 筆記",
"done": false
}
所以 REST 名字裡的 Representation 不是多餘的。Server 可以在內部用 PostgreSQL 儲存資料,但 client 不需要知道資料表怎麼設計;它只要透過 API 收到一份 resource 的表示即可。這也接回 API 最基本的價值:外部程式只需要理解介面,不需要理解整個內部實作。
GET:取得 resource,不應該順便把它改掉
MDN 將 GET 定義為要求取得指定 resource 的 representation。最典型的例子就是讀資料:
GET 在 HTTP 語意上屬於 safe method,也就是 client 發出 GET 時,預期它只是讀取,不會要求伺服器改變資源狀態。這不代表伺服器完全不能記 log、更新流量統計或做快取,而是「修改主要 resource」不應該成為 GET 的目的。
這個差別很實際。如果你設計一個 GET /delete-user/42,瀏覽器預抓、搜尋引擎 crawler 或快取系統只要正常存取 URL,就可能觸發刪除。HTTP 的 method 語意本來就是讓 client、中介層和 server 對 request 有共同預期。
POST:把資料提交給 resource,不只是「新增」
POST 常被初學者背成「Create」,因為建立新資料確實很常用 POST。例如:
但 POST 的語意比「新增」更廣。MDN 的描述是把一個 entity 提交給指定 resource,而這通常會造成 server 狀態改變或其他 side effect。付款、寄信、啟動轉檔、提交表單,都可能合理地使用 POST,即使結果不是新增一列資料。
所以看到 POST 時,不要直接翻譯成「新增」。比較準確的想法是:把這份內容交給這個 resource 處理。 至於處理結果是建立 resource、觸發動作,還是進入一段 workflow,要看 API 的契約。
PUT:把指定 resource 換成這份表示
PUT 最容易被簡化成「Update」,但 HTTP 語意更具體。MDN 將 PUT 描述為用 request content 取代 target resource 目前的 representation:
PUT /tasks/42
{
"title": "整理 REST API 筆記",
"done": true
}
這也是為什麼「只想改一個欄位」時常會看到 PATCH。PATCH 的目的就是對 resource 做部分修改,而不是把 PUT 單純理解成「任何更新都用它」。不同 API 仍可能有自己的設計取捨,所以真正串接時要看文件,不要只靠 method 名字猜 payload 的規則。
DELETE:要求刪除指定 resource
DELETE 的語意最直觀:要求刪除 target resource。
但「刪除」不一定代表資料庫裡那一列立刻永久消失。服務端可以做 soft delete、保留稽核紀錄、延後背景清理,或因權限不足拒絕 request。HTTP method 描述的是 client 對 resource 的要求,不是強迫 server 採用某一種資料庫實作。
為什麼還要知道 safe 和 idempotent?
HTTP 對 method 還有兩個很重要的性質。Safe 關心的是 request 是否以修改 server state 為目的;idempotent 則關心同一個 request 重複做多次,預期效果是否和做一次相同。
GET 是 safe,也應該是 idempotent。PUT 是 idempotent:你把第 42 筆任務設定成同一份內容一次或五次,最終狀態理論上相同。DELETE 也具有 idempotent 語意:第一次可能成功刪除,第二次可能回 404,但「這個 resource 已不存在」的最終效果沒有繼續改變。POST 通常不保證 idempotent;同一筆「建立訂單」request 重送兩次,可能真的產生兩張訂單。
這不是考試名詞而已。行動網路斷線時,client 可能不知道 request 到底有沒有送成功;反向代理也可能重試部分 request。理解 method 的 idempotence,會直接影響 retry、付款、建立訂單和資料一致性的設計。
Stateless 不是「伺服器不能存資料」
REST 另一個常被誤解的 constraint 是 stateless。它不是叫 server 不准有 database,也不是每次 request 都要匿名。核心是 client 到 server 的每個 request,應該攜帶 server 完成這次 request 所需的資訊,而不是依賴「前一個 request 我跟你說過什麼」這種隱藏的對話狀態。
例如 request 可以帶 access token,server 再去查使用者、權限與資料。這仍然可以是 stateless 的互動。相反地,如果 server 必須記住「這個 client 上一步走到流程第三頁,所以這次沒有任何識別資訊也知道他是誰」,就會增加跨 request 的會話耦合。REST 的 stateless constraint 主要是在降低這種依賴,讓 request 比較容易獨立處理、擴充與分散。
REST API 不是 CRUD 表格換一個名字
很多教材會用 CRUD 對照 HTTP method:Create → POST、Read → GET、Update → PUT、Delete → DELETE。這張表適合入門,但不能當完整定義。REST 在意的是 resource、representation、uniform interface 和 request semantics;CRUD 則只是資料操作的四個常見分類。
因此一個 API 可以有 POST 卻不是建立資料,也可以用 PATCH 更新部分欄位;同樣地,資料庫做了 DELETE,不代表外部 API 就必須暴露 DELETE。API 是系統願意提供給 client 的契約,不是資料庫操作的直接鏡像。
把常見四個 method 放在一起:
GET:取得 resource 的 representation。
POST:把資料提交給 resource 處理,常用於建立或觸發動作。
PUT:用 request content 取代指定 resource 的 representation。
DELETE:要求刪除指定 resource。
Status code 是 response 的另一半語意
Method 告訴 server「client 想做什麼」,HTTP status code 則告訴 client「結果怎麼樣」。成功讀取常見 200 OK;建立新 resource 常見 201 Created;成功但沒有 response body 時可能是 204 No Content;找不到 resource 常見 404 Not Found;權限、輸入衝突或 server error 也各有對應的狀態碼。
所以真正讀一支 API,不只要看 endpoint。至少要一起看 method + URL + headers + request body + response body + status code。這些東西合在一起,才構成完整的 HTTP API 契約。
REST 之所以常見,不是因為 GET、POST 四個字特別漂亮,而是它讓 Web 已經存在的 HTTP 語意成為系統共同語言。前端、server、proxy、cache 和各種工具都比較容易理解 request 想做什麼。當介面設計得一致,client 就不用為每個 endpoint 重新學一套完全不同的規則。