天天看點

RESTful API 設計。最佳實踐簡而言之。

設計 HTTP 和 RESTful API 可能很棘手,因為沒有官方和強制執行的标準。基本上,有許多實作 API 的方法,但其中一些已在實踐中得到驗證并被廣泛采用。這篇文章涵蓋了建構 HTTP 和 RESTful API 的最佳實踐。我們将讨論 URL 結構、HTTP 方法、建立和更新資源、設計關系、有效負載格式、分頁、版本控制等等。

RESTful API 設計。最佳實踐簡而言之。

2018 年更新

我完全重寫了這篇文章。我重新通路并擴充了現有部分并添加了許多新部分:對 HTTP 方法和狀态代碼的新概述、PATCH、明确 PUT 和 POST 的語義、字段、data設計關系、REST 與 RPC 風格的 API、可演化性、版本控制方法、基于鍵集分頁、JSON:API、JSON:API 啟發的有效負載格式。

每個資源使用兩個 URL

一個 URL 用于集合,一個 URL 用于單個資源:

# URL that represents a collection of resources
/employees          
# URL that represents a single resource
/employees/56       
           

始終使用複數名詞

更喜歡

/employees
/employees/21
           

超過

/employee
/employee/21
           

确實,這是一個品味問題,但複數形式更常見。此外,它更直覺,尤其是在集合 URL 上使用 GET 時(GET /employee傳回多個員工)。但最重要的是:避免混合使用複數和單數名詞,這會造成混淆并容易出錯。

對資源使用名詞而不是動詞

這将使您的 API 保持簡單并減少 URL 的數量。不要這樣做:

/getAllEmployees
/getAllExternalEmployees
/createEmployee
/updateEmployee
           

相反,在一小組 URL 上使用可用的 HTTP 方法來表達所需的操作。請參閱下一節。

HTTP 方法

使用 HTTP 方法操作您的資源

GET /employees
GET /employees?state=external
POST /employees
PUT /employees/56
           

使用 URL 指定您要使用的資源。使用 HTTP 方法指定如何處理此資源。使用 GET、POST、PUT、PATCH 和 DELETE 這五個 HTTP 方法,您可以提供 CRUD 功能(建立、讀取、更新、删除)及其他功能。

  • Read:使用 GET 讀取資源。
  • 建立:使用 POST 或 PUT 建立新資源。
  • 更新:使用 PUT 和 PATCH 更新現有資源。
  • Delete:使用 DELETE 删除現有資源。

了解 HTTP 方法的語義

幂等性的定義:當我們可以安全地一遍又一遍地執行請求并且所有請求都導緻相同狀态時,HTTP 方法是幂等的。

  • 得到幂等的隻讀。GET從不更改伺服器端資源的狀态。它不能有副作用。是以,可以安全地緩存響應。例子:GET /employees- 列出所有員工GET /employees/1- 顯示員工 1 的詳細資訊
  • 放幂等!可用于建立和更新常用于更新(完全更新)。示例:PUT /employees/1- 更新員工 1(不常見:建立員工 1)要使用 PUT 建立,用戶端需要預先知道整個 URL(包括 ID)。這并不常見,因為伺服器通常會生成 ID。是以,當隻有一個元素且 URL 明确時,通常使用 PUT 進行建立。示例:PUT /employees/1/avatar- 建立或更新員工 1 的頭像。每個員工隻有一個頭像。始終在請求中包含整個有效負載。全有或全無。PUT 并不意味着用于部分更新(請參閱 PATCH)。
  • 郵政不是幂等的!用于建立示例:POST /employees建立一個新員工。新 URL 在 Header 中傳回給用戶端Location(例如Location: /employees/12)。多個 POST 請求導緻/employees許多新的不同員工(這就是 POST 不是幂等的原因)。
  • 修補幂等的用于部分更新。示例:PATCH /employees/1- 使用負載中包含的字段更新員工 1。員工 1 的其他字段沒有更改。
  • 删除幂等的用于删除。例子:DELETE /employees/1

在資源集合 URL 上釋出以建立新資源

用于建立新資源的用戶端-伺服器互動看起來如何?

RESTful API 設計。最佳實踐簡而言之。

使用 POST 建立新資源

用戶端向資源集合 URL 發送 POST 請求/employees。HTTP 正文包含新資源“Paul”的屬性。RESTful Web 服務為新員工生成一個 ID,在其内部模型中建立員工并向用戶端發送響應。此響應包含狀态代碼 201(已建立)和一個LocationHTTP 标頭,訓示建立的資源可通路的 URL。PUT 用于更新資源的單個資源 URL

RESTful API 設計。最佳實踐簡而言之。

使用 PUT 更新現有資源。

  1. 用戶端向單個資源 URL 發送 PUT 請求/employee/21。PUT 請求的 HTTP 主體包含員工的所有字段,每個字段都将在伺服器端更新。
  2. REST 服務使用 ID 21 更新員工的name和status并使用 HTTP 狀态代碼 200 确認更改。

使用 PATCH 進行資源的部分更新

PUT不應該用于部分更新。PUT 應該隻用于資源的完全替換。每次發送所有字段(盡管您隻想更新一個字段)可能會導緻在并行更新的情況下意外覆寫。此外,驗證的實施很困難,因為您必須同時支援兩種用例:同時建立(某些字段不能null)和更新(null标記不應更新的字段的值)。是以不要使用 PUT 并隻發送應該更新的字段。PUT 請求中缺少的字段應被視為null值并清空資料庫字段或觸發驗證錯誤。

相反,使用 PATCH 進行部分更新。僅發送應更新的字段。這樣,請求負載非常簡單,不同字段的并行更新不會覆寫不相關的字段,驗證變得更容易,值的語義是明确的null(對于 PUT 和 PATCH)并且您可以節省帶寬。

例如,以下 PATCH 請求僅更新status字段而不更新name.

RESTful API 設計。最佳實踐簡而言之。

使用 PATCH 并僅發送您想要更新的字段。

實作旁注:除了所描述的“隻發送你喜歡更新的内容”方法( JSON:API也推薦),還有JSON-PATCH。它是 PATCH 請求的有效負載格式,描述了應該對資源執行的一系列更改。然而,對于許多用例來說,實施和矯枉過正是很棘手的。有關更多詳細資訊,請檢視文章“ PUT vs PATCH vs JSON-PATCH ”。

将實際資料包裝在一個data字段中

GET /employees傳回字段中的對象清單data:

{
  "data": [
    { "id": 1, "name": "Larry" }
    , { "id": 2, "name": "Peter" }
  ]
}
           

GET /employees/1傳回字段中的單個對象data:

{
  "data": { 
    "id": 1, 
    "name": "Larry"
  }
}
           

PUT、POST 和 PATCH 請求的負載還應包含data具有實際對象的字段。

優點:

  • 有空間可以添加中繼資料(例如用于分頁、連結、棄用警告、錯誤消息)
  • 一緻性
  • 相容JSON:API 标準

将查詢字元串 (?) 用于可選參數和複雜參數

不要這樣做:

GET /employees
GET /externalEmployees
GET /internalEmployees
GET /internalAndSeniorEmployees
           

保持您的 URL 簡單且 URL 設定小。為您的資源選擇一個基本 URL 并堅持使用。将複雜性或可選參數移至查詢字元串。

GET /employees?state=internal&title=senior
GET /employees?id=1,2
           

JSON:API 的過濾方式是:

GET /employees?filter[state]=internal&filter[title]=senior
GET /employees?filter[id]=1,2
           

使用 HTTP 狀态碼

RESTful Web 服務應該使用合适的 HTTP 狀态響應代碼來響應用戶端的請求。

  • 2xx– 成功 – 一切正常。
  • 4xx– 用戶端錯誤——如果用戶端做錯了什麼(例如,用戶端發送了一個無效的請求或者他沒有被授權)
  • 5xx– 伺服器錯誤 – 伺服器端故障(嘗試處理請求時出現的錯誤,例如資料庫故障、依賴服務不可用、程式設計錯誤或不應發生的狀态)

考慮可用的 HTTP 狀态代碼。但是,請注意,使用所有這些可能會讓您的 API 使用者感到困惑。使使用的 HTTP 狀态代碼集保持較小。通常使用以下代碼:

  • 2xx:成功200 好201 建立
  • 3xx:重定向301 永久移動304 未修改
  • 4xx:用戶端錯誤400 錯誤請求401未經授權403禁止通路404 未找到410 沒了
  • 5xx:伺服器錯誤500内部伺服器錯誤

不要過度使用 404。嘗試更精确。如果資源可用,但不允許使用者檢視它,則傳回 403 Forbidden。如果資源曾經存在但現在已被删除或停用,請使用 410 Gone。

提供有用的錯誤資訊

除了适當的狀态代碼之外,您還應該在 HTTP 響應正文中提供對錯誤的有用且詳細的描述。這是一個例子。

要求:

GET /employees?state=super
           

回複:

// 400 Bad Request
{
  "errors": [
    {
      "status": 400,
      "detail": "Invalid state. Valid values are 'internal' or 'external'",
      "code": 352,
      "links": {
        "about": "http://www.domain.com/rest/errorcode/352"
      }
    }
  ]
}
           

提議的錯誤負載結構受到JSON:API 标準的啟發。

提供用于通過您的 API 導航的連結 (HATEOAS)

理想情況下,您不要讓您的客戶構造 URL 來使用您的 REST API。讓我們考慮一個例子。

客戶想要通路員工的工資報表。salaryStatements是以,他必須知道他可以通過将查詢參數附加到員工 URL(例如)來通路薪水報表/employees/21/salaryStatements。這種字元串連接配接容易出錯、脆弱且難以維護。如果您更改在 REST API 中通路薪水報表的方式(例如現在使用“薪水報表”或“工資單”),所有用戶端都将中斷。

最好在您的回複中提供客戶可以關注的連結。例如,對的響應GET /employees可能如下所示:

{
  "data": [
    {
      "id":1,
      "name":"Paul",
      "links": [
        {
          "salary": "http://www.domain.com/employees/1/salaryStatements"
        }
      ]
    }
  ]
}
           

如果客戶完全依賴連結來擷取薪水報表,那麼即使您更改 API,他也不會中斷,因為客戶将始終獲得有效的 URL(隻要您在 URL 更改時更新連結)。另一個好處是您的 API 變得更具自我描述性,客戶不必經常查找文檔。

适當地設計關系

讓我們假設每個人employee都有一個manager和幾個teamMembers。在 API 中設計關系基本上有三種常見的選擇:連結、側載和嵌入。

它們都是有效的,正确的選擇取決于用例。基本上,您應該根據用戶端的通路模式以及可容忍的請求量和負載大小來設計關系。

連結

{
  "data": [
    { 
      "id": 1, 
      "name": "Larry",
      "relationships": {
        "manager": "http://www.domain.com/employees/1/manager",
        "teamMembers": [ 
          "http://www.domain.com/employees/12",
          "http://www.domain.com/employees/13"
        ]
        //or "teamMembers": "http://www.domain.com/employees/1/teamMembers"
      }
    }
  ]
}
           
  • 小的有效載荷大小。這很好,如果客戶不需要 themanager和 theteamManager每次。
  • 許多請求。如果幾乎每個客戶都需要這些資料,那就太糟糕了。可能需要許多額外的請求;在更壞的情況下,對每個員工來說。然後乘以員工擁有的每個關系(manager等等teamMembers)。
  • 客戶必須将資料拼接在一起才能獲得全局。

側載

我們可以引用與外鍵的關系,并将引用的實體也放在有效負載中,但在專用字段下included。這種方法也稱為“複合文檔”。

{
  "data": [
    { 
      "id": 1, 
      "name": "Larry",
      "relationships": {
        "manager":  5 , 
        "teamMembers": [ 12, 13 ]
      }
    }
  ],
  "included": {
    "manager": {
      "id": 5, 
      "name": "Kevin"
    },
    "teamMembers": [
      { "id": 12, "name": "Albert" }
      , { "id": 13, "name": "Tom" }
    ]
  }
}
           

用戶端還可以通過查詢參數(如 )控制側載實體GET /employees?include=manager,teamMembers。

  • 我們相處一個單一的請求。
  • 量身定制的有效載荷大小。沒有重複(例如,即使他被許多員工引用,你也隻能傳遞一次經理)
  • 用戶端仍然必須将資料拼接在一起以解決關系,這可能非常麻煩。

嵌入

{
  "data": [
    { 
      "id": 1, 
      "name": "Larry",
      "manager": {
        "id": 5, 
        "name": "Kevin"
      },
      "teamMembers": [
        { "id": 12, "name": "Albert" }
        , { "id": 13, "name": "Tom" }
      ]
    }
  ]
}
           
  • 對客戶最友善。是可以直接按照關系得到實際資料。
  • 如果用戶端不需要,關系可能會白白加載。
  • 增加的有效負載大小和重複。引用的實體可能會被嵌入多次。

對屬性名稱使用 CamelCase

使用 CamelCase 作為您的屬性辨別符。

{ "yearOfBirth": 1982 }
           

不要使用下劃線 ( year_of_birth) 或大寫 ( YearOfBirth)。通常,您的 RESTful Web 服務将由用 JavaScript 編寫的用戶端使用。通常,用戶端會将 JSON 響應轉換為 JavaScript 對象(通過調用var person = JSON.parse(response))并調用其屬性。是以,堅持 JavaScript 約定是一個好主意,它可以使 JavaScript 代碼更具可讀性和直覺性。

// Don't
person.year_of_birth // violates JavaScript convention
person.YearOfBirth // suggests constructor method

// Do
person.yearOfBirth
           

使用動詞進行操作

有時對 API 調用的響應不涉及資源(如計算、翻譯或轉換)。例子:

//Reading
GET /translate?from=de_DE&to=en_US&text=Hallo
GET /calculate?para2=23¶2=432

//Trigger an operation that changes the server-side state
POST /restartServer
//no body

POST /banUserFromChannel
{ "user": "123", "channel": "serious-chat-channel" }
           

在這種情況下,不涉及任何資源。相反,伺服器執行一個操作并将結果傳回給用戶端。是以,您應該在 URL 中使用動詞而不是名詞,以清楚地區分操作(RPC 樣式 API)和 REST 端點(用于模組化域的資源)。

建立那些 RPC 風格的 API 而不是 REST API 适合操作。通常,它比嘗試 RESTful 操作(如PATCH /serverwith {"restart": true})更簡單、更直覺。根據經驗,REST 非常适合與域模型互動,而 RPC 适合操作。有關詳細資訊,請檢視“ Understanding RPC Vs REST For HTTP APIs ”。

提供分頁

一次傳回資料庫的所有資源幾乎不是一個好主意。是以,您應該提供分頁機制。兩種流行的方法是:

  • 基于偏移的分頁
  • 基于鍵集的分頁又名 Continuation Token 又名 Cursor(推薦)

基于偏移的分頁

一個非常簡單的方法是使用參數offset和limit,它們在資料庫中是衆所周知的。

/employees?offset=30&limit=15 # returns the employees 30 to 45
           

如果用戶端省略了參數,您應該使用預設值(如offset=0和limit=100)。永遠不要傳回所有資源。如果檢索成本更高,則應降低限制。

/employees                    # returns the employees 0 to 100
           

您可以提供擷取下一頁或上一頁的連結。隻需建構具有适當偏移量和限制的 URL。

GET /employees?offset=20&limit=10
           
{
  "pagination": {
    "offset": 20,
    "limit": 10,
    "total": 3465,
  },
  "data": [
    //...
  ],
  "links": {
    "next": "http://www.domain.com/employees?offset=30&limit=10",
    "prev": "http://www.domain.com/employees?offset=10&limit=10"
  }
}
           

基于鍵集的分頁(又名 Continuation Token,Cursor)

提出的基于偏移量的分頁很容易實作,但有嚴重的缺點。它們很慢(SQL 的OFFSET子句對于大數變得非常慢)并且不安全(在分頁期間發生更改時很容易錯過元素)。

這就是為什麼最好使用索引列。假設我們的員工有一個索引列data_created,并且集合資源/employees?pageSize=100傳回按此列排序的最老的 100 名員工。現在,用戶端隻需要擷取dateCreated最後一名員工的時間戳,并使用查詢參數createdSince在此時繼續。

GET /employees?pageSize=100                
# The client receives the oldest 100 employees sorted by `data_created`
# The last employee of the page has the `dataCreated` field  with 1504224000000 (= Sep 1, 2017 12:00:00 AM)

GET /employees?pageSize=100&createdSince=1504224000000
# The client receives the next 100 employees since 1504224000000. 
# The last employee of the page was created on 1506816000000. And so on.
           

這已經解決了基于偏移量的分頁的許多缺點,但它仍然不完美并且對用戶端來說不是很友善。

  • 最好通過向日期添加附加資訊(如 id)來建立所謂的延續令牌,以提高可靠性和效率。
  • 此外,您應該在有效負載中為該令牌提供一個專用字段,這樣用戶端就不必通過檢視元素來弄清楚它。您甚至可以更進一步并提供next連結。

是以GET /employees?pageSize=100傳回:

{
  "pagination": {
    "continuationToken": "1504224000000_10",
  },
  "data": [
    // ...
    // last element:
    { "id": 10, "dateCreated": 1504224000000 }
  ],
  "links": {
    "next": "http://www.domain.com/employees?pageSize=100&continue=1504224000000_10"
  }
}
           

該next連結使 API 真正成為 RESTful,因為用戶端隻需通過這些連結 (HATEOAS) 即可在集合中分頁。無需手動建構 URL。此外,您可以簡單地更改 URL 結構而不會破壞用戶端(可進化性)。

有關更多詳細資訊,請檢視有關 Web API 分頁的專門文章:

  • Web API Pagination with the 'Timestamp_Offset_Checksum' Continuation Token - 不再推薦所提出的方法,但該文章很好地介紹了整個主題(包括基于偏移量的分頁)。
  • 使用“Timestamp_ID”延續令牌的 Web API 分頁- 我建議使用這種方法。它還包含對現有的基于鍵集的分頁方法的概述。

檢視 JSON:API

您至少應該看看JSON:API。它是 JSON 負載和 HTTP 服務資源(MIME 類型application/vnd.api+json:)的标準格式。我個人并不遵循所有建議,因為其中一些建議對我來說有點過于正式和矯枉過正。在我看來,實作的靈活性通常不是必需的,但它使實施變得複雜而沒有提供任何好處。但這是一個品味問題,遵循标準基本上是個好主意。我用它作為靈感并選擇那些對我有意義的元素。随意對 JSON:API 做出自己的決定。

確定 API 的可演化性

避免破壞性變化

理想情況下,REST API(與每個 API 一樣)應該是穩定的。基本上,重大更改(如更改整個有效負載格式或 URL 方案)不應該發生。但是,我們如何才能在不破壞用戶端的情況下繼續改進我們的 API?

  • 進行向後相容的更改。添加字段是沒有問題的(隻要用戶端能容忍)。
  • 重複和棄用。為了更改現有字段(重命名或更改結構),您可以在舊字段旁邊添加新字段并在文檔中棄用舊字段。一段時間後,您可以删除舊字段。
  • 利用超媒體和 HATEOAS。隻要 API 用戶端使用響應中的連結在 API 中導航(并且不手動制作 URL),您就可以安全地更改 URL 而不會破壞用戶端。
  • 使用新名稱建立新資源。如果新的業務需求導緻全新的領域模型和工作流,您可以建立新的資源。這通常非常直覺,因為領域模型無論如何都有一個新名稱(源自企業名稱)。示例:租賃服務現在也可以租用自行車和賽格威。car是以,資源的舊概念/cars不再有效。引入了vehicle具有新資源的新域模型。/vehicles它與舊/cars資源一起提供。

将業務邏輯放在伺服器端

不要讓您的服務成為轉儲資料通路層,它通過直接公開您的資料庫模型(低級 API)來提供 CRUD 功能。這會産生高耦合。

  • 業務邏輯轉移到用戶端,并且經常在用戶端和伺服器之間複制(隻考慮驗證)。我們必須保持兩者同步。
  • 通常,用戶端耦合到伺服器的資料庫模型。

我們應該避免建立轉儲資料通路 API,因為它們會導緻伺服器和用戶端之間的高耦合,因為業務工作流正在用戶端和伺服器之間分布。反過來,這使得新的業務需求可能需要更改用戶端和伺服器并破壞 API。是以 API/系統不是那麼可進化的。

是以,我們應該建構進階/基于工作流的 API,而不是低級 API。例如:不要為資料庫中的訂單實體提供簡單的 CRUD 服務。不需要用戶端知道要取消訂單,用戶端必須将訂單 PUT 到/order/1其中包含特定取消有效負載(反映資料庫模型)的通用資源。這會導緻高耦合(用戶端的業務邏輯和領域知識;暴露的資料庫模型)。

相反,提供專用資源/order/1/cancelation并在訂單資源的有效負載中添加指向它的連結。用戶端可以導航到取消 URL 并發送定制的取消有效負載。将此有效負載映射到資料庫模型的業務邏輯在伺服器中完成。此外,伺服器可以很容易地更改 URL 而不會破壞用戶端,因為用戶端隻是跟随連結。此外,決定邏輯(是否可以取消訂單)現在位于伺服器中:如果可以取消,伺服器将連結添加到訂單有效負載中的取消資源。是以用戶端隻需要檢查取消連結是否存在(例如,知道他是否應該繪制取消按鈕)。是以,我們将領域知識從用戶端移回伺服器。隻需觸摸伺服器即可輕松應用取消條件的更改,這反過來又使系統可以進化。無需更改 API。

如果您想閱讀更多有關此主題的資訊,我推薦Oliver Gierke 的演講REST beyond the obvious – API design for ever evolving systems 。

考慮 API 版本控制

然而,您最終可能會遇到上述方法不起作用并且您确實必須提供不同版本的 API 的情況。版本控制允許您在新版本下釋出 API 的不相容和破壞性更改,而不會破壞用戶端。他們可以繼續使用舊版本。客戶可以按照自己的速度遷移到新版本。

這個話題在社群中引起了激烈的争論。您應該考慮到您最終可能會長期建構和維護(!)不同版本的 API,這是非常昂貴的。

如果您正在建構内部 API,您很可能了解所有客戶。是以,執行重大更改可以再次成為一種選擇。但這将需要更多的溝通和協調部署。

然而,這裡有兩種最流行的版本控制方法:

  • 通過 URL 進行版本控制:/v1/
  • 通過AcceptHTTP 标頭進行版本控制:(Accept: application/vnd.myapi.v1+json内容協商)

通過 URL 進行版本控制

隻需将 API 的版本号放在每個資源的 URL 中即可。

/v1/employees
           

優點:

  • 對于 API 開發人員來說極其簡單。
  • API 用戶端非常簡單。
  • 可以複制和粘貼 URL。

缺點:

  • 不是 RESTful。
  • 破壞網址。用戶端必須維護和更新 URL。

嚴格來說,這種方法不是 RESTful,因為 URL 永遠不應該改變。這防止容易進化。将版本放在 URL 中有一天會破壞 API,您的客戶必須修複 URL。問題是,用戶端更新 URL 需要付出多少努力?如果答案是“隻有一點點”,那麼 URL 版本控制可能沒問題。

由于其簡單性,URL 版本控制非常流行,并被 Facebook、Twitter、Google/YouTube、Bing、Dropbox、Tumblr 和 Disqus 等公司廣泛使用。

通過AcceptHTTP 标頭(内容協商)進行版本控制

更 RESTful 的版本控制方式是通過 HTTP 請求标頭利用内容協商Accept。

GET /employees
Accept: application/vnd.myapi.v2+json
           

在這種情況下,用戶端請求資源的版本 2 /employees。是以我們将不同的 API 版本視為/employees資源的不同表示,這非常 RESTful。v2當用戶端僅請求時,您可以将可選和預設設定為最新版本Accept: application/vnd.myapi+json。但公平地警告他,如果他不固定版本,他的應用程式将來可能會崩潰。

優點:

  • 網址保持不變
  • 被認為是 RESTFul
  • HATEOAS 友好型

缺點:

  • 使用難度稍大。客戶必須注意标題。
  • 無法再複制和粘貼 URL。

關于版本控制的個人想法

建立新 API 時,請嘗試不使用 URL 版本控制。特别是内部 API 可能根本不需要現有資源的真正版本 2。您可能會接受“避免重大更改”部分中描述的方法。如果您最終确實需要現有資源的新版本,您仍然可以進行内容協商并利用标Accept頭。但總的來說,最好建構一個 API,它首先使破壞性更改的可能性降低(例如,通過建構進階/流程 API 并将業務邏輯保留在伺服器中)。

關于版本化 API 的正确方法以及什麼是 RESTful 什麼不是。人們真的很沮喪。我更喜歡務實。對我來說,如果您在涉及版本控制(并使用 URL 版本控制)時不關心 REST 理論,那完全沒問題,隻要它對您、您的客戶有用,并且您知道即将到來的維護成本。“Protip”:談論“Web API”或“HTTP API”而不是“REST API”,以誠實地說明與 REST 的一緻性并安撫 REST 狂熱者。;-)

延伸閱讀

  • 我強烈推薦Phil Sturgeon 的《Build APIs You Won't Hate》一書
  • 我寫了一篇關于在 Java 中測試 RESTful 服務的最佳實踐的文章。
  • JSON:API 标準
  • 對 REST 的回應是Phil Sturgeon 的新 SOAP(REST 混淆解釋)
  • 了解 HTTP API 的 RPC 與 REST作者:Phil Sturgeon

作者:Philipp Hauer

出處:https://phauer.com/2015/restful-api-design-best-practices/