簡述使用REST API 的最佳實踐

語言: CN / TW / HK

簡述 使 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 https://api.github.com/users/codemazeblog

響應:

{

"login": "CodeMazeBlog",

"id": 29179238,

"avatar_url": "https://avatars0.githubusercontent.com/u/29179238?v=4",

"gravatar_id": "",

"url": "https://api.github.com/users/CodeMazeBlog",

"html_url": "https://github.com/CodeMazeBlog",

"followers_url": "https://api.github.com/users/CodeMazeBlog/followers",

"following_url": "https://api.github.com/users/CodeMazeBlog/following{/other_user}",

"gists_url": "https://api.github.com/users/CodeMazeBlog/gists{/gist_id}",

"starred_url": "https://api.github.com/users/CodeMazeBlog/starred{/owner}{/repo}",

"subscriptions_url": "https://api.github.com/users/CodeMazeBlog/subscriptions",

"organizations_url": "https://api.github.com/users/CodeMazeBlog/orgs",

"repos_url": "https://api.github.com/users/CodeMazeBlog/repos",

"events_url": "https://api.github.com/users/CodeMazeBlog/events{/privacy}",

"received_events_url": "https://api.github.com/users/CodeMazeBlog/received_events",

"type": "User",

"site_admin": false,

"name": "Code Maze",

"company": "Code Maze",

"blog": "https://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 https://api.twitter.com/1.1/account/settings.json 響應:狀態碼400Twitter response

  {"errors":[{"code":215,"message":"Bad Authentication data."}]}

Twitter為您提供狀態程式碼和錯誤程式碼,並簡要描述了所發生錯誤的性質。他們讓您在“ 響應程式碼” [26] 頁面上查詢程式碼。

臉書:

請求:  GET https://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 https://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> https://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版本來對其進行版本控制: https://api.example.com/v1/authors/2/blogposts/13

這樣,只要API發生重大更改,我們就可以始終增加API版本號(例如v2,v3…)。這也向使用者發出訊號,表明已發生了翻天覆地的變化,在使用新版本時,請務必小心。

檔案的重要性

這是不言而喻的。您可能是世界上最好的API設計人員,但是 如果沒有文件,您的API就像死了一樣。

正確的文件對於每個軟體產品和Web服務都是 必不可少 的。

我們可以通過保持一致並使用清晰和描述性的語法來幫助使用者。但是,好的文件頁面並沒有真正的替代品。

一些很好的例子:

https://www.twilio.com/docs/api/rest/

https://developers.facebook.com/docs/

https://developers.google.com/maps/documentation/

還有很多其他...

有許多工具可以幫助您記錄您的API,但是不要忘記讓人蔘與其中,只有一個人可以正確地理解另一個人。至少現在是這樣(看著你)。

結論

我們討論了REST API構建的許多概念,並介紹了一些頂級REST API最佳實踐。在一次提供這些API時,您可能會覺得有些奇怪或難以接受,但是請嘗試自己建立REST API。並嘗試實現一些您在這裡學到的REST API最佳實踐。

References

[1] HTTP系列文章:  https://code-maze.com/http-series/

[2] 第1部分:  https://code-maze.com/http-series-part-1/

[3] 什麼是REST?:  https://code-maze.com/top-rest-api-best-practices/#whatisrest

[4] REST是否繫結到HTTP?:  https://code-maze.com/top-rest-api-best-practices/#restbound

[5] REST和HATEOAS支援:  https://code-maze.com/top-rest-api-best-practices/#hateoas

[6] RESTful API是什麼意思?:  https://code-maze.com/top-rest-api-best-practices/#whatdoesitmean

[7] REST過多又稱為RESTafarian綜合徵:  https://code-maze.com/top-rest-api-best-practices/#restafarian

[8] 抽象與具體API:  https://code-maze.com/top-rest-api-best-practices/#abstractvsconcrete

[9] URI格式(名詞,不是動詞)。正確網址與錯誤網址示例:  https://code-maze.com/top-rest-api-best-practices/#urlformat

[10] 錯誤處理:  https://code-maze.com/top-rest-api-best-practices/#errorhandling

[11] 狀態碼:  https://code-maze.com/top-rest-api-best-practices/#statuscodes

[12] 安全:  https://code-maze.com/top-rest-api-best-practices/#security

[13] REST API版本控制:  https://code-maze.com/top-rest-api-best-practices/#versioning

[14] 檔案的重要性:  https://code-maze.com/top-rest-api-best-practices/#documentation

[15] Roy Fielding:  https://en.wikipedia.org/wiki/Roy_Fielding

[16] 體系結構樣式和基於網路的軟體體系結構設計:  https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

[17] HTTP:  https://code-maze.com/http-series/

[18] HATEOAS:  https://en.wikipedia.org/wiki/HATEOAS

[19] 超媒體:  https://en.wikipedia.org/wiki/Hypermedia

[20] 客戶端-伺服器體系結構:  https://code-maze.com/http-series-part-2

[21] Roy的論文ch.5.2.2:  https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

[22] 可快取的:  https://code-maze.com/http-series-part-2/#caching

[23] HTTP方法:  https://code-maze.com/the-http-reference/#requestmethods

[24] Mike Schinkel:  http://mikeschinkel.com/about/

[25] 。:  http://mikeschinkel.com/about/

[26] 響應程式碼”:  https://developer.twitter.com/en/docs/basics/response-codes

[27] HTTP狀態程式碼:  https://code-maze.com/the-http-reference/#statuscodes

[28] KISS原則:  https://en.wikipedia.org/wiki/KISS_principle

[29] 此處:  https://code-maze.com/the-http-reference

[30] 在CodeMaze上總結的:  https://code-maze.com/the-http-reference

[31] REST API安全的:  https://blog.restcase.com/top-5-rest-api-security-guidelines/

[32] 基本身份驗證或摘要身份驗證之:  https://code-maze.com/http-series-part-4/

[33] HTTP安全:  https://code-maze.com/http-series-part-5/