簡述使用REST API 的最佳實踐
簡述 使 用 REST API 的 最佳 實踐
Facebook,Google,Github,Netflix,Amazon和Twitter等許多巨頭都擁有自己的REST(ful)API,您可以訪問它們來獲取甚至寫入資料。
但是,為什麼所有都需要REST?
那樣好嗎,為什麼如此盛行?
當然,這不是傳達訊息的唯一方法嗎?
REST和HTTP有什麼區別?
好吧,事實證明 REST非常靈活,並且與 Internet所基於的主要協議 HTTP相容 。由於它是一種架構風格而不是標準,因此它 提供了實現各種設計最佳實踐的大量自由 。以及聽說它與語言無關?你一定覺得它很棒吧。
在此部落格文章中,我們的目標是儘可能清楚地解釋REST,以便您可以清楚地瞭解何時以及如何使用REST,以及它的本質。
我們將介紹一些基礎知識和定義,並展示一些 REST API最佳實踐 。這應該為您提供了以您喜歡的任何編碼語言實現REST API所需的全部知識。
如果您對HTTP不太熟悉,建議您閱讀我們的 HTTP系列文章 [1] ,或者至少閱讀其中的 第1部分 [2] ,這樣您可以更輕鬆地理解這些資料。
因此,在這篇文章中,我們將討論:
關於REST:
• 什麼是REST? [3] • REST是否繫結到HTTP? [4] • REST和HATEOAS支援 [5] • RESTful API是什麼意思? [6] • REST過多又稱為RESTafarian綜合徵 [7]
REST API最佳做法:
• 抽象與具體API [8] • URI格式(名詞,不是動詞)。正確網址與錯誤網址示例 [9] • 錯誤處理 [10] • 狀態碼 [11] • 安全 [12] • REST API版本控制 [13] • 檔案的重要性 [14]
那麼REST本質上是什麼?
REST(代表性狀態轉移)是 Roy Fielding [15] 在其博士學位中創立的一種建築風格。UC Irvine的論文“ 體系結構樣式和基於網路的軟體體系結構設計 [16] ”。他與HTTP 1.1同步提出了這種觀點。
我們主要將REST用作 在全球資訊網上的計算機系統之間進行通訊的 一種方式。
REST是否繫結到HTTP?
根據定義,似乎與Http強制繫結?其實並非如此。儘管您可以將其他一些應用程式協議與REST一起使用,但是在實現REST時, HTTP [17] 仍然是應用程式協議中無可爭議的冠軍。
REST和HATEOAS支援
作為應用程式狀態引擎的HATEOAS或 超媒體 是每個可擴充套件且靈活的REST API的重要功能。
該 HATEOAS [18] 約束建議,客戶端和伺服器通訊完全採用了 超媒體 [19] 。
使用超媒體有幾個優點:
• 使API設計人員能夠在每個響應中包括他們所能提供的一切,以正確地提供一件事以及與相關端點的超媒體連結,從而使設計脫鉤 • 幫助API更優雅地發展和成熟 • 為使用者提供更深入地探索API的方法
因此很明顯,HATEOAS在 設計時考慮了耐用性 。
GitHub的工作方式如下:
GET http://api.github.com/users/codemazeblog
響應:
{
"login": "CodeMazeBlog",
"id": 29179238,
"avatar_url": "http://avatars0.githubusercontent.com/u/29179238?v=4",
"gravatar_id": "",
"url": "http://api.github.com/users/CodeMazeBlog",
"html_url": "http://github.com/CodeMazeBlog",
"followers_url": "http://api.github.com/users/CodeMazeBlog/followers",
"following_url": "http://api.github.com/users/CodeMazeBlog/following{/other_user}",
"gists_url": "http://api.github.com/users/CodeMazeBlog/gists{/gist_id}",
"starred_url": "http://api.github.com/users/CodeMazeBlog/starred{/owner}{/repo}",
"subscriptions_url": "http://api.github.com/users/CodeMazeBlog/subscriptions",
"organizations_url": "http://api.github.com/users/CodeMazeBlog/orgs",
"repos_url": "http://api.github.com/users/CodeMazeBlog/repos",
"events_url": "http://api.github.com/users/CodeMazeBlog/events{/privacy}",
"received_events_url": "http://api.github.com/users/CodeMazeBlog/received_events",
"type": "User",
"site_admin": false,
"name": "Code Maze",
"company": "Code Maze",
"blog": "http://code-maze.com",
"bio": "A practical programmers' resource.",
...
}
如您所見,除了客戶端請求的關鍵資訊之外,您還可以在響應中找到一堆相關的超媒體連結,這些連結將您帶到您可以自由瀏覽的API的其他部分。
RESTful API是什麼意思?
“ RESTful”意味著一些功能:
• 客戶端-伺服器體系結構 [20] : 完整的服務由作為整個系統前端的“客戶端”和作為後端的“伺服器”組成 • 無狀態: 伺服器不應在不同請求之間儲存任何狀態。會話狀態完全由客戶負責。按照REST定義: 所有REST互動都是無狀態的。也就是說,每個請求都包含聯結器理解該請求所需的所有資訊,而與之前的任何請求無關。( Roy的論文ch.5.2.2 [21] )\ • 可快取的 [22] : 客戶端應該能夠將響應儲存在快取中以提高效能
因此,RESTful API是一項遵循這些規則的服務(希望如此),並使用 HTTP方法 [23] 來操縱資源集。
但是為什麼我們需要或使用RESTful API?
因為它們為我們提供了一種簡單,靈活和可擴充套件的方式來製作可通過Internet進行通訊的分散式應用程式。
我們可以擁有更多的REST方法嗎?
是的,你猜對了。是的,我們可以
正如 Mike Schinkel [24] 定義的那樣,對於狂熱地遵循REST的人們來說甚至還有一個短語 。 [25]
RESTifarian是Roy T. Fielding在他的博士論文第五章中定義的REST軟體架構風格的狂熱支持者。論文在UCIrvine。你可以在rest - discussion郵件列表中找到野外的RESTifarians。但是要小心,RESTifarians在討論休息的細節時可能是極其細緻的,正如我最近在參與列表時所瞭解到的。
太多的事情都是不好的。
我們需要一點 實用主義 才能做出好的應用程式和服務。瞭解和理解一種理論很重要,但是該理論的實現是區分不良與良好與卓越應用的區別。所以要聰明,要牢記終端使用者。
因此,讓我們走一些使API變得“光彩”的重要點,使使用者的生活變得更加輕鬆。
抽象與具體API
在開發軟體時,我們經常使用抽象和多型來獲取大多數應用程式。我們想重用盡可能多的程式碼。
那麼我們也應該這樣寫我們的API嗎?
好吧,API並非完全如此。對於REST API, 具體要比abstract好 。你能猜出為什麼嗎?
讓我向您展示一些示例:
讓我們看兩個API版本。它是最好有有一個的API /entities
,或者有一個API /owners
, /blogs
並 /blogposts
分別?
作為開發人員,哪一個對您更具描述性?您想使用哪個API?
我總是會選擇第二個。
URI格式(名詞,不是動詞)。正確網址與錯誤網址示例
這是另一種REST API最佳實踐。您應該如何格式化端點?
如果使用軟體開發方法,您將得到如下所示的結果:
/getAllBlogPosts
/updateBlogPost/12
/deleteBlogPost/12
/getAuthorById/3
/deleteAuthor/3
/updateAuthor/3
您明白了……會有很多端點,每個端點都在做其他事情。有一個更好的系統可以解決這些問題。
將資源視為名詞,將HTTP方法視為動詞。如果這樣做,最終將得到如下結果:
GET /blogposts
–獲取所有部落格文章
GET /blogposts/12
–獲取ID為12的部落格文章
POST /blogposts
–新增新的部落格文章並返回詳細資訊
DELETE /blogposts/12
–刪除ID為12的部落格文章
GET /authors/3/blogposts
–獲取ID為3的作者的所有部落格文章
這是建立API的更簡潔,更精確的方法。對於終端使用者而言,這是顯而易見的,並且有一種解決方法。
通過使用單數而不是複數來表示資源名稱,可以使其更加簡潔。那取決於你。
錯誤處理
API構建的另一個重要方面。有幾種處理錯誤的好方法。
讓我們看看頂級狗如何做到這一點:
推特:
•
請求: GET http://api.twitter.com/1.1/account/settings.json
•
響應:狀態碼400Twitter response
{"errors":[{"code":215,"message":"Bad Authentication data."}]}
Twitter為您提供狀態程式碼和錯誤程式碼,並簡要描述了所發生錯誤的性質。他們讓您在“ 響應程式碼” [26] 頁面上查詢程式碼。
臉書:
•
請求: GET http://graph.facebook.com/me/photos
•
響應:狀態碼400Facebook Response
{ "error" : { "message" : "An active access token must be used to query information about the current user." , "type" : "OAuthException" , "code" : 2500 , "fbtrace_id" : "DzkTMkgIA7V" }}
Facebook為您提供了更具描述性的錯誤訊息。
特威里奧:
•
請求: GET http://api.twilio.com/2010-04-01/Accounts/1234/IncomingPhoneNumbers/1234
•
響應:狀態碼404
<? xml version = '1.0' encoding = 'UTF-8' ?> <TwilioResponse> <RestException> <Code> 20404 </Code> <Message> The requested resource /2010-04-01/Accounts/1234/IncomingPhoneNumbers/1234 was not found </Message> <MoreInfo> http://www.twilio.com/docs/errors/20404 </MoreInfo> <Status> 404 </Status> </RestException></TwilioResponse>
Twilio預設為您提供XML響應,並提供指向文件的連結,您可以在其中找到錯誤的詳細資訊。
如您所見,錯誤處理的方法因實現而異。
重要的是 不要讓REST API的使用者“結束通話” ,不知道發生了什麼,或者漫無目的地在StackOverflow的浪費中徘徊,尋找解釋。
狀態碼
在設計REST API時,我們通過使用 HTTP狀態程式碼 [27] 與API使用者進行通訊 。狀態程式碼很多,描述了多種可能的響應。
但是,我們應該使用多少? 我們在每種情況下都應該有嚴格的狀態碼嗎?
就像生活中的許多事情一樣, KISS原則 [28] 也適用於這裡。那裡有70多個狀態程式碼。你內心瞭解他們嗎?潛在的API使用者會全部瞭解它們,還是會再次使用Google搜尋?
大多數開發人員都熟悉最常見的狀態程式碼:
•
**200 OK**
•
**400 Bad Request**
•
**500 Internal Server Error**
從這三個開始,您可以涵蓋REST API的大多數功能。
其他常見的程式碼包括:
•
**201 Created**
•
**204 No Content**
•
**401 Unauthorized**
•
**403 Forbidden**
•
**404 Not Found**
我們可以使用它們來幫助使用者快速找出結果。如果您感覺到狀態程式碼的描述性不如我們在“錯誤處理”部分中討論的那樣,則可能應該包含某種訊息。再一次,我們需要務實,通過使用 數量有限的程式碼 和描述性訊息來幫助使用者。
您可以在 此處 [29] 找到完整的HTTP狀態程式碼列表,以及 在CodeMaze上總結的 [30] 其他有用的HTTP內容 。
安全
關於 REST API安全的 [31] 說法不多,因為 REST不處理安全問題 。它依賴於諸如 基本身份驗證或摘要身份驗證之 [32] 類的標準HTTP機制 。
每個請求都應 通過HTTPS進行 。
有很多技巧可以提高REST API的安全性,但是由於REST的無狀態性,因此在實施它們時必須謹慎。記住最後一個請求的狀態超出了視窗, 應該 在 客戶端儲存和驗證狀態。
時間戳記和日誌記錄請求也可以有所幫助。
關於這個話題還有很多要說的,但這超出了本文的範圍。我們有一個不錯的職位 HTTP安全 [33] 在這裡CodeMaze如果您想了解更多關於這一點。
REST API版本控制
您已經編寫了REST API,它已經非常成功,許多人已經使用它並對此感到滿意。但是,您擁有的多汁的新功能會破壞系統的其他部分。重大變化。
不用擔心,有解決方案!
在開始製作您的API之前,我們可以通過在端點之前加上API版本來對其進行版本控制: http://api.example.com/v1/authors/2/blogposts/13
這樣,只要API發生重大更改,我們就可以始終增加API版本號(例如v2,v3…)。這也向使用者發出訊號,表明已發生了翻天覆地的變化,在使用新版本時,請務必小心。
檔案的重要性
這是不言而喻的。您可能是世界上最好的API設計人員,但是 如果沒有文件,您的API就像死了一樣。
正確的文件對於每個軟體產品和Web服務都是 必不可少 的。
我們可以通過保持一致並使用清晰和描述性的語法來幫助使用者。但是,好的文件頁面並沒有真正的替代品。
一些很好的例子:
http://www.twilio.com/docs/api/rest/
http://developers.facebook.com/docs/
http://developers.google.com/maps/documentation/
還有很多其他...
有許多工具可以幫助您記錄您的API,但是不要忘記讓人蔘與其中,只有一個人可以正確地理解另一個人。至少現在是這樣(看著你)。
結論
我們討論了REST API構建的許多概念,並介紹了一些頂級REST API最佳實踐。在一次提供這些API時,您可能會覺得有些奇怪或難以接受,但是請嘗試自己建立REST API。並嘗試實現一些您在這裡學到的REST API最佳實踐。
References
[1]
HTTP系列文章: http://code-maze.com/http-series/
[2]
第1部分: http://code-maze.com/http-series-part-1/
[3]
什麼是REST?: http://code-maze.com/top-rest-api-best-practices/#whatisrest
[4]
REST是否繫結到HTTP?: http://code-maze.com/top-rest-api-best-practices/#restbound
[5]
REST和HATEOAS支援: http://code-maze.com/top-rest-api-best-practices/#hateoas
[6]
RESTful API是什麼意思?: http://code-maze.com/top-rest-api-best-practices/#whatdoesitmean
[7]
REST過多又稱為RESTafarian綜合徵: http://code-maze.com/top-rest-api-best-practices/#restafarian
[8]
抽象與具體API: http://code-maze.com/top-rest-api-best-practices/#abstractvsconcrete
[9]
URI格式(名詞,不是動詞)。正確網址與錯誤網址示例: http://code-maze.com/top-rest-api-best-practices/#urlformat
[10]
錯誤處理: http://code-maze.com/top-rest-api-best-practices/#errorhandling
[11]
狀態碼: http://code-maze.com/top-rest-api-best-practices/#statuscodes
[12]
安全: http://code-maze.com/top-rest-api-best-practices/#security
[13]
REST API版本控制: http://code-maze.com/top-rest-api-best-practices/#versioning
[14]
檔案的重要性: http://code-maze.com/top-rest-api-best-practices/#documentation
[15]
Roy Fielding: http://en.wikipedia.org/wiki/Roy_Fielding
[16]
體系結構樣式和基於網路的軟體體系結構設計: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
[17]
HTTP: http://code-maze.com/http-series/
[18]
HATEOAS: http://en.wikipedia.org/wiki/HATEOAS
[19]
超媒體: http://en.wikipedia.org/wiki/Hypermedia
[20]
客戶端-伺服器體系結構: http://code-maze.com/http-series-part-2
[21]
Roy的論文ch.5.2.2: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
[22]
可快取的: http://code-maze.com/http-series-part-2/#caching
[23]
HTTP方法: http://code-maze.com/the-http-reference/#requestmethods
[24]
Mike Schinkel: http://mikeschinkel.com/about/
[25]
。: http://mikeschinkel.com/about/
[26]
響應程式碼”: http://developer.twitter.com/en/docs/basics/response-codes
[27]
HTTP狀態程式碼: http://code-maze.com/the-http-reference/#statuscodes
[28]
KISS原則: http://en.wikipedia.org/wiki/KISS_principle
[29]
此處: http://code-maze.com/the-http-reference
[30]
在CodeMaze上總結的: http://code-maze.com/the-http-reference
[31]
REST API安全的: http://blog.restcase.com/top-5-rest-api-security-guidelines/
[32]
基本身份驗證或摘要身份驗證之: http://code-maze.com/http-series-part-4/
[33]
HTTP安全: http://code-maze.com/http-series-part-5/
- C# 面向物件程式設計之里氏替換原則實戰解析
- C# 面向物件程式設計之開閉原則實戰解析
- C# 面向物件程式設計之單一職責原則實戰解析
- C#單元測試的使用(三)
- .NET基礎知識快速通關(9)
- .NET基礎知識快速通關(6)
- .NET基礎知識快速通關(5)
- 面試寶典之.NET基礎知識快速通關(1)
- 填坑 | .NET 在Docker中訪問MSSQL報錯
- 如何分析.NET Core HttpClient請求異常
- 理解C#泛型原理
- 萬字長文講解:什麼是「抽象」?
- 簡述使用REST API 的最佳實踐
- 如何基於.NET Core構建分散式檔案儲存系統?
- 利用SOS擴充套件庫進入高階.NET6程式的除錯
- 淺議開發者面臨的資訊偏差影響因素
- 【新書速遞】龍芯開源LoongArch版,學會造計算機!
- .NET誕生20週年 .NET 7有什麼新東西?
- 基於.NET 製作一個氣象站 IoT 應用
- [探索 .NET 6]02 比較 WebApplicationBuilder 和 Host