什麼是 RESTful API?從日常生活理解 REST 架構原理
2025年7月13日
我們每天的生活中,都會與數十甚至上百個網路服務互動,而在用不同的 App 的過程中,多數人可能沒有意識到,自己在用的 App 背後正悄悄地與其他系統對話。事實上,如果 App 沒有跟背後的系統溝通,我們將會無法拿到最新的資訊。但 App 是如何跟背後的系統溝通呢? 天氣 App 如何取得即時資料?社群媒體的 App 拿到最新貼文?
在現代的應用程式開發中,這些之所以能夠發生,是因為背後有 API 這個關鍵要素。而在眾多的 API 撰寫方式中,有一個特別熱門的 REST 原則。理解 REST 是對前端與後端工程師來說,都必須要掌握的基本。在這篇文章中,我們將探討什麼是具有 REST 風格的 API (俗稱 RESTful API),讓讀者能掌握 RESTful API 的基本原則。
什麼是 API?
在談 RESTful API 之前,先讓我們回顧一下什麼是 API。讓我們用餐廳點餐來比喻,當今天到了某間餐廳,相信多數人不會直接走進廚房跟廚師說要做什麼菜、怎麼做,而是會透過服務生點餐。告訴服務生自己想要什麼,服務生就會為我們送上餐點。在這個過程中,我們不需要知道廚房如何運作、使用的食材如何進口,只需要表達自己要什麼菜 (例如「我要一份蛋炒飯」)。
API(Application Programming Interface,應用程式介面)的運作方式就像餐廳中的服務生。它是應用程式和其他系統之間的溝通橋樑,就像服務生是你與餐廳之間的橋樑。當 App 需要取得資料,例如使用者資訊、天氣資料、社群貼文,就會向 API 發出請求 (這就像跟服務生點餐一樣),而 API 負責取得資料並回傳結果 (這就像服務生送餐來一樣)。
舉例來說,天氣 App 本身不會在手機中存下全世界所有地方的天氣資料,而是向氣象服務的 API 查詢「台北現在的氣溫是幾度?」,API 回傳資料後 App 再顯示給使用者看。
API 如果沒有統一規格會怎麼樣?
在理解什麼是 API 後,接著讓我們來談實際在前後端開發的具體例子。假設今天要開發一個要跟 GitHub 溝通的 App,我們需要取得使用者資訊、建立專案庫、管理議題。
這個 App 應該如何與 GitHub 的伺服器溝通? 要能跟 GitHub 的伺服器溝通,就要按照 GitHub 訂定 API 的方式來拿資料。這時問題來了,如果這個 App 要串接其他服務的 API,這時如果不同公司的規範不同,使用不同的指令格式、回傳不同的資料格式、用不同的方式處理錯誤。這就會導致開發者需要為每個服務學習不同的使用方式。
由於現在的 App 背後很可能同時串接各類不同服務,假如每一種的形式都不同,對開發者來說會非常困擾。而 REST 解決了這個問題。REST 提供的基本結構和規則,讓所有 API 都有一致的使用方式,開發者學會 REST 的風格後,就能應用到其他 API 的開發與使用上。
什麼是 REST?
具體來說,REST 是指 Representational State Transfer(表徵狀態轉移),是 Roy Fielding 在 2000 年提出的概念。雖然名字聽起來很複雜,但它其實是一套讓 API 統一運作的簡單規則。
就像交通號誌在全世界都有相同意義(紅燈停、綠燈行),REST 為 API 的運作方式提供了通用規範。這樣所有開發者都能用相同的邏輯來設計和使用 API。而符合 REST 規範的 API 又會被稱為 RESTful API,以下的六個核心原則,是 RESTful API 共用的特徵。
REST 的六個核心原則
1. 統一介面 (Uniform Interface)
統一介面 (Uniform Interface) 是指所有 API 都要用一致的方式來設計。以 GitHub API 為例:
GET /users/explainthis # 取得使用者資訊
GET /users/explainthis/repos # 取得使用者的專案庫
POST /user/repos # 建立新的專案庫
PATCH /repos/explainthis/Hello-World # 更新專案庫
DELETE /repos/explainthis/Hello-World # 刪除專案庫
相信大家能從上面這幾個不同的 API 看出其中共有的規律,在 RESTful API 中,會有 URL 說明你要操作的資源 (例如 /users/explainthis
),同時搭配 HTTP 方法(GET、POST、PATCH、DELETE)說明你要做什麼動作。
這些不同的 HTTP 方法分別代表:
- GET:取得資源(「給我看看某個東西」)
- POST:建立新資源(「幫我建立一個新的東西」)
- PATCH:部分更新資源(「幫我修改某個東西的部分內容」)
- DELETE:刪除資源(「幫我刪除某個東西」)
這些方法就像是我們在日常生活中的動作,GET 像「查看」,POST 像「新增」,PATCH 像「修改」,DELETE 像「刪除」。透過這樣的規範,要串接 API 的開發者,就能夠一眼看出某個 API 是做什麼用的。
2. 無狀態 (Stateless)
無狀態 (Stateless) 代表每個請求都包含伺服器處理所需的所有資訊,換句話說伺服器不會幫忙「記住」之前的請求。
你可能會問「無狀態有什麼好處?」,假設你有 10 台伺服器。無狀態設計下,任何伺服器都能處理任何請求。但有狀態設計下,小明的所有請求都要去找同一台伺服器。
這會造成如果某台伺服器當機,那台伺服器負責的特定使用者,就會被影響,因為其他台伺服器無法幫忙處理;同時,也可能會有某台伺服器超載時,其他伺服器卻可能閒置 (同樣地,因為沒辦法幫忙處理請求)。無狀態設計讓每個請求都獨立且完整,任何伺服器都能處理。這讓系統更好擴展,也更容易維護。
3. 客戶端-伺服器分離 (Client-Server Separation)
客戶端-伺服器分離 (Client-Server Separation) 的好處在於,客戶端 (App) 和伺服器 (API) 完全獨立。更新 App 不需要改伺服器,更新伺服器也不需要改 App。
因為沒有互相綁死,要擴展也容易。以 GitHub 為例,同樣地 API,可以用在網頁、手機 App、桌面 App;假如伺服器跟客戶端綁死,要支援不同的客戶端,就要開發不同的 API,會讓開發成本上升不少。
4. 可快取(Cacheable)
伺服器回應要明確說明資料可不可以快取,以及快取多久。下面這段,就像伺服器端對客戶端說「這個資料在 1 小時 (3600 秒) 內都有效,這段時間內不用再向我請求。」。
HTTP/1.1 200 OK
Cache-Control: max-age=3600
Content-Type: application/json
{"name": "GitHub 使用者指南", "updated_at": "2023-01-15T10:30:00Z"}
當能夠快取,伺服器整體回應速度就會變快,因為在快取仍有效的期間,不需用再去重複請求;因為不用重複請求,這對伺服器端的負擔也能減少。
5. 分層系統(Layered System)
系統是分層的,每一層只需要知道直接下方的那一層。你不需要知道背後有多少台伺服器。
當你呼叫 api.github.com
時,請求可能會經過:
- 負載平衡器(分散流量)
- 快取伺服器(儲存常用資料)
- 認證服務(驗證身份)
- 資料庫伺服器(儲存資料)
每一層負責自己的事情,然後把請求傳給下一層。你只需要對一個 URL 發出請求,其他的都交給分層系統處理。
這種分層架構的好處在於讓整個系統變得更加靈活和可靠。當某一層出現問題時,其他層不會受到影響。同時,每一層都可以根據需要進行優化或擴展,例如在流量增加時增加更多負載平衡器,或是在快取伺服器容量不足時增加新的快取節點。對於開發者來說,這種設計讓 API 的使用變得非常簡單,不需要了解背後複雜的架構細節,只要知道一個統一的入口點就能存取所有功能。
6. 按需編碼(Code on Demand)(可選)
伺服器可以傳送程式碼給客戶端執行。最常見的例子就是當你瀏覽網頁時,伺服器會傳送 HTML、CSS 和 JavaScript 給你的瀏覽器,瀏覽器接收到這些程式碼後就在瀏覽器中執行,產生使用紙ㄜ看到的網頁效果。
這種做法的好處是讓系統更有彈性,伺服器可以根據不同情況傳送不同的程式碼,而不需要預先在客戶端安裝所有可能用到的功能。不過在一般的 RESTful API 設計中,這個原則被標記為「可選」,因為大多數 API 只需要傳送資料就足夠。
具體來說,什麼樣的 API 算 RESTful?
在了解完 REST 的核心原則後,讓我們用 GitHub API 為例,來看看這些原則在實務上如何應用:
首先,API 用資源導向的 URL,像下面這樣
/users/123 # 使用者 123 的資源
/users/123/repositories # 使用者 123 的所有專案庫
/repositories/456 # 專案庫 456 的資源
/repositories/456/issues # 專案庫 456 中的所有議題
接著,每個 API 的 HTTP 方法都明確定義,讓人能一眼看出其功能為何
GET /users/123 # 取得使用者資料
POST /users # 建立新使用者
PUT /users/123 # 完整更新使用者資料
PATCH /users/123 # 部分更新使用者資料
DELETE /users/123 # 刪除使用者
最後,所有 API 回應都有相同的格式:
{
"id": 583231,
"login": "octocat",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"type": "User",
"created_at": "2011-01-25T18:44:36Z"
}
在這樣的設計下,每支 API 的回應都是乾淨可預測的。如前面談到,這種一致性讓開發者不需要為每個 API 學習不同的使用方式,因為所有 RESTful API 都遵循相同的規範。當你熟悉了一個 RESTful API 的使用方式後,你就能快速上手其他遵循 REST 原則的 API。這不僅降低了學習成本,也減少了開發與維護的時間,讓團隊能更專注於業務邏輯的實現,而不是花時間適應各種不同的 API 格式。
HTTP 狀態碼的重要性
在 RESTful API 中,溝通不只是單純的資料交換。除了回傳你要的資料,伺服器還會透過 HTTP 狀態碼告訴客戶端處理結果如何。這些狀態碼就像是一套通用的溝通語言,讓 API 能夠清楚表達「請求成功了」、「資料格式有問題」、「你沒有權限」或「伺服器出錯了」等不同情況。對開發者來說,這些標準化的狀態碼讓錯誤處理變得更簡單,因為開發者可以根據不同的狀態碼採取對應的處理方式,而不用猜測到底發生了什麼問題。
以下是常見的 HTTP 狀態碼:
成功(2xx)
- 200 OK:請求成功,这就是你要的資料
- 201 Created:新資源建立成功
- 204 No Content:請求成功,但沒有資料返回
客戶端錯誤(4xx)
- 400 Bad Request:請求格式有問題
- 401 Unauthorized:需要先登入認證
- 403 Forbidden:已登入但沒有權限
- 404 Not Found:找不到資源
- 409 Conflict:資源衝突或已存在
伺服器錯誤(5xx)
- 500 Internal Server Error:伺服器內部出錯
- 503 Service Unavailable:伺服器暫時無法使用
總結
希望透過這篇文章,讓讀者們有更了解 RESTful API 是什麼。REST 不是單純的技術規格,而是一種系統溝通的思維方式。遵循 REST 原則能建立可預測、可擴展且易於使用的 API。
推薦讀者們,如果想要更了解 RESTful,可以在未來使用不同 API 時,用上面提到的原則,來檢視該 API 有多 RESTful,例如 URL 設計清楚嗎?HTTP 方法用得合理嗎?回應格式一致嗎?理解這些模式也會讓你成為更好的開發者。
加入 E+ 成長計畫
如果你覺得這篇內容有幫助,喜歡我們的內容,歡迎加入 ExplainThis 籌辦的 E+ 成長計畫,透過每週的深度主題文,以及技術討論社群,讓讀者在前端、後端、軟體工程的領域上持續成長。