邱敬幃 Pardn Chiu
目錄什麼是 REST?REST 的基本原則資源 (Resources)表現層 (Representation)狀態轉換 (Stateless)一致性 (Consistency)連通性 (Uniform Interface)REST 的應用設計 RESTful API定義資源使用 HTTP 方法使用正確的狀態碼支援查詢參數使用版本控制身分驗證和授權使用 HATEOAS(Hypermedia As The Engine Of Application State)核心概念實際範例使用 Express 實作 API系列文章相關連結
標籤

RESTful API 該怎麼設計?

Node.js: JavaScript 的後端魔法 (9)

230次觀看 1收藏 後端開發 Nodejs RESTfulAPI
RESTful API 是一種設計風格,旨在促進資源的有效管理和互動。這種設計風格以 REST (Representational State Transfer) 為基礎,是一種通用的概念,適用於各種不同的應用程式和服務。
本篇將深入研究 REST 是什麼,如何設計 RESTful API,以及如何使用 Express 實作 API。

什麼是 REST?

REST,即 Representational State Transfer,是一種軟體架構風格,旨在使網路上的系統資源能夠以一致且有條理的方式進行交互。提出 REST 這一概念的人是 Roy Fielding,他在他的博士論文《Architectural Styles and the Design of Network-based Software Architectures》中首次描述了這種風格。

REST 的基本原則

REST 的設計基於一組簡單而直觀的原則,這些原則使其成為設計 Web 服務和 API 的理想選擇。

資源 (Resources)

在 REST 中,所有的事物都被視為資源,每個資源都有一個唯一的識別符號 (通常是 URI)。這可以是實體 (如一個用戶)、一項服務 (如一個天氣服務),或者其他類型的資源。

表現層 (Representation)

資源的狀態以及相關資訊在 REST 中以表現層的形式進行傳輸。這通常是使用 JSON 或 XML 格式,但也可以是其他格式,具體取決於應用程式的需求。

狀態轉換 (Stateless)

REST 是一種狀態轉換的架構風格,這表示每一個請求都應該包含資源的所有資訊,伺服器不應該保存客戶端的狀態。每個請求都應該是獨立的且完整的。

一致性 (Consistency)

一致性是指在整個系統中,資源的表現層的形式應該保持一致。這意味著相同的資源應該以相似的方式被表示,使客戶端能夠預測和理解資源的結構。

連通性 (Uniform Interface)

REST 使用一個統一的接口,這是其最強大和最具有彈性的部分之一。這包括以下原則:

  • 資源標識
    每個資源都應該有一個唯一的 URI。
  • 表現層操縱
    通過對資源的表現層進行操作,例如 GET、POST、PUT 或 DELETE。
  • 資源的自描述性
    每個資源都應該包含足夠的信息,讓客戶端理解如何操作它。

REST 的應用

REST 不僅僅是一種設計 Web 服務的風格,還廣泛應用於許多領域,包括移動應用程式、物聯網(IoT)裝置、雲端服務等。它的簡單性和靈活性使其成為設計現代應用程式的理想選擇。

REST 這一概念是為了解決分散式超媒體系統的通信問題而提出的。其基本原則強調了簡單性、一致性和無狀態性,這使得 REST 成為一個強大而通用的設計風格。在當今的複雜應用程式環境中,REST 仍然是許多系統架構的首選,並為 Web 開發者提供了一個堅實的基礎。


設計 RESTful API

在現代軟體開發中,設計一個強大而易於使用的 API 是不可或缺的一部分。RESTful API 是一種具有一致性和可擴展性的 API 設計風格,它遵循 REST 原則,為開發者提供了一個清晰而直觀的方式來構建和使用 Web 服務。本文將深入探討如何設計一個優雅且功能豐富的 RESTful API。

定義資源

RESTful API 的核心是資源。資源可以是任何你的應用程式中需要暴露的事物,如用戶、產品、文章等。每個資源都應有一個唯一的識別符號,通常是一個 URI。例如:

  • 用戶:/users
  • 產品:/products
  • 文章:/posts

定義清晰且具有語義的資源層次結構是建構 RESTful API 的第一步。

使用 HTTP 方法

RESTful API 使用標準的 HTTP 方法來執行操作。以下是常見的 HTTP 方法和它們的用途:

  • GET:獲取資源的資訊。
  • POST:創建一個新的資源。
  • PUT:更新現有資源。
  • DELETE:刪除資源。

使用正確的 HTTP 方法對應到預期的操作,使 API 更加直觀和易於理解。

使用正確的狀態碼

HTTP 狀態碼是 API 與客戶端通信的一部分,提供有關請求結果的信息。使用正確的狀態碼能夠提供更好的 API 體驗。例如:

  • 200 OK:成功的 GET 請求。
  • 201 Created:成功的 POST 請求,並創建了新的資源。
  • 204 No Content:成功的 DELETE 請求,且無返回內容。
  • 404 Not Found:未找到所請求的資源。

更多狀態碼說明保留至後續講解

支援查詢參數

RESTful API 應該支援查詢參數,以允許客戶端進行更細粒度的資源檢索。例如允許使用者透過?page=1&limit=10來分頁獲取資源。

使用版本控制

隨著 API 的演進,可能會對其進行更改。為了確保舊的客戶端不會因為 API 的變動而中斷,建議使用版本控制。可以將版本號添加到 URI 中,例如/v1/users

身分驗證和授權

保護 API 是至關重要的。使用適當的身分驗證機制,如 OAuth,確保只有合法的使用者能夠訪問敏感資源。同時,設計授權機制以確保每個使用者僅能訪問其具有權限的資源。

使用 HATEOAS(Hypermedia As The Engine Of Application State)

HATEOAS 是一種在 RESTful API 中提供動態資源連結的方法,使得客戶端可以通過這些連結來導航整個應用程式的狀態。這種方式的目標是使 API 變得更具自描述性,降低客戶端對 URI 結構的硬編碼程度,提高系統的可擴展性。

核心概念
  • 自描述性 (Self-Descriptiveness)
    HATEOAS 的主要目標之一是讓 API 成為自描述的。這表示 API 的每個響應都包含了客戶端可能需要的所有信息,包括下一步可用的操作。這樣,客戶端就無需事先知道所有的 URI 結構,而是通過解析 API 的響應來動態地導航。
  • 動態資源連結(Dynamic Resource Links)
    API 的響應中包含了指向其他資源的連結,這些連結可用於執行相關操作。這些動態生成的連結是根據資源的當前狀態和可能的操作而生成的,因此它們可以隨著 API 的演進而動態改變。
  • 導航(Navigation)
    客戶端通過解析 API 的響應,可以動態地導航到不同的資源或執行不同的操作。這種導航的方式類似於用戶在瀏覽器中點擊超連結的方式,使得客戶端不再需要事先知道所有可能的 URI。
實際範例

讓我們通過一個簡單的範例來理解 HATEOAS。假設有一個 Blog API,當獲取文章列表時,API 的響應可能如下所示:

  1. {
  2.     "posts": [
  3.         {
  4.             "id": 1,
  5.             "title": "title 1",
  6.             "user": "Pardn Ltd",
  7.             "links": [
  8.                 {
  9.                     "rel": "self",
  10.                     "href": "/posts/1"
  11.                 },
  12.                 {
  13.                     "rel": "comments",
  14.                     "href": "/posts/1/comments"
  15.                 }
  16.             ]
  17.         },
  18.         {
  19.             "id": 2,
  20.             "title": "title 2",
  21.             "user": "Pardn Chiu",
  22.             "links": [
  23.                 {
  24.                     "rel": "self",
  25.                     "href": "/posts/2"
  26.                 },
  27.                 {
  28.                     "rel": "comments",
  29.                     "href": "/posts/2/comments"
  30.                 }
  31.             ]
  32.         }
  33.     ],
  34.     "links": [
  35.         {
  36.             "rel": "self",
  37.             "href": "/posts"
  38.         }
  39.     ]
  40. }

在這個例子中,每篇文章的資源都包含了一組連結,這些連結表示了該資源可以執行的操作。例如,"rel": "self"表示這是該文章的自身連結,"rel": "comments"表示這是該文章評論的連結。同時,整個文章列表也包含了一個 self 連結,表示這是文章列表的自身連結。


使用 Express 實作 API

現在,我們將使用 Express 來實作一個簡單的 RESTful API。以下是一個示例,實現了如何獲取文章資源:

  1. // 模擬有一個包含文章的資料陣列
  2. const posts = [
  3.     { id: 1, title: "title 1", content: "..." },
  4.     { id: 2, title: "title 2", content: "..." },
  5. ];
  6. // 獲取所有文章
  7. app.get("/posts", (req, res) => {
  8.     res.json(articles);
  9. });
  10. // 獲取單篇文章
  11. app.get("/posts/:id", (req, res) => {
  12.     const id = parseInt(req.params.id);
  13.     const post = posts.find(=> e.id === id);
  14.     if (post) {
  15.         res.json(post);
  16.     } 
  17.     else {
  18.         res.status(404).json({ err: "404" });
  19.     }
  20. });

在這個例子中,我們使用了GET方法來獲取所有文章和單篇文章,並使用正確的狀態碼進行回應。


系列文章


相關連結