天天看點

restful

api開發近年來一直是一個非常有趣和具有挑戰性的網頁開發。網際網路曆史上的可擴充性在使用者數量較少的時候并不是很重要,是以獨立應用程式在很大程度上表現良好。然而,随着不同移動裝置的大量湧現,今天的使用者現在可以使用來自許多不同裝置的相同應用程式,這導緻開發人員需要擴充其應用程式。

就是說,建立一個通用的api是有意義的,可以輕松有效地擴充使用者不斷變化的需求,而不是開發不同的獨立應用程式。因為建立api有幾種不同的技術,是以沒有設計api的真正标準或方法。但是,正确地設計api有幾個商定的最佳做法。在沒有實際标準的情況下,很難制定僵化的慣例。然而,将要讨論的大部分内容來自于将舊版應用程式移動到api模型的真實世界體驗,或者從頭開始建立新的api,這不僅具有彈性和穩定性,而且還具有可擴充性和快速性。

良好的api設計的重要性

沒有人喜歡在網站上看到404錯誤,特别是當有人将部落格文章或文章加入書簽以備将來使用時。無論什麼時候需要更改url,使用者都需要使用該url,url修改對seo也不利。在沒有正确抽象的情況下設計api可能需要稍後更改url。雖然重定向可以解決這個問題,但這是一個避免重定向的seo最佳做法。是以,在深入了解api設計之前設計标準是有意義的,并且在建立url之前将其重點放在具體的細節和業務名稱上。

在本系列中,我們将繼續關注api開發的标準。本系列涵蓋不同的技術标準,具體取決于具體的業務情況。假設api設計适用于基于http的restful服務。

1,名詞,無動詞

api設計的第一條規則是在url中使用名詞。我們還應該使用http動詞來委派動詞。例如,以下url包含get http方法:

chanderdhall.com/gettrainings

由于http支援get方法,是以api需要以标準動詞get的方式進行設計,進而産生以下url:

chanderdhall.com/trainings

原始網址有什麼問題?雖然url看起來很好,非常直覺,但如果使用者嘗試使用不同的http動詞呢?假設使用者想要使用以下url:

post chanderdhall.com/gettrainings

這顯然是自我毀滅的。我們正在嘗試添加教育訓練,網址似乎給我們提供了錯誤的解釋,這可能會将使用者混淆到網址的實際使用中。這一規則适用于其餘的動詞。您可以建立一個http delete請求,說明gettrainings如下面的解決方案所示:

get chanderdhall.com/trainings

post chanderdhall.com/trainings

put chanderdhall.com/trainings

delete chanderdhall.com/trainings

您可能會注意到,無論動詞是什麼,url都不會更改。

2.每個資源的兩個基本url

下一個标準是基于保持簡單,愚蠢(kiss)原則。我們真的需要每個資源兩個基本url:一個用于多個值,一個用于特定值。在這個例子中,我們需要知道提供的多個教育訓練,或者我們需要找到一個特定的教育訓練,因為我們有必要的資訊來檢索它。同樣,該資訊可以是教育訓練id或名稱。以下顯示使用兩個基本url與四個http動詞的不同結果:

http get(讀)

get chanderdhall.com/trainings - 檢索所有教育訓練

get chanderdhall.com/trainings/123 - 檢索id = 123的所有教育訓練

http post(插入)

post chanderdhall.com/trainings - 建立一個新的播客

post chanderdhall.com/trainings/123 - 錯誤

為什麼使用post方法進行身份識别教育訓練?這是因為id是由資料庫生成的,然後被傳回給用戶端。為什麼要建立這種類型的功能,如果我們要做的是傳回一個錯誤?這是因為我們正在設計一個api,我們不想給使用者一個錯誤的印象,他的請求在實際上沒有被接受。是以,重要的是我們需要處理錯誤。

http put(更新)

put chanderdhall.com/trainings - 批量更新所有教育訓練

put chanderdhall.com/trainings/123 - 如果存在,請更新特定教育訓練。如果不存在,則會引發錯誤。這樣做是因為我們不希望put方法執行插入,因為post方法是插入的正确動詞。

http删除

get chanderdhall.com/trainings - 删除所有教育訓練。確定該人員被認證并被授權删除教育訓練。

get chanderdhall.com/trainings/123 - 删除具有授權權限id = 123的教育訓練。它應該檢查特定訓練是否真的存在。如果教育訓練不存在,那麼它應該抛出一個錯誤,指出沒有找到資源。

3.關系

當您開發協作時,您的api應該非常直覺。以下網址直覺地表明,要求教育訓練人員由id為14的教育訓練人員和id為114的教育訓練提供教育訓練:

get / trainers / 14 / training / 114

我們已經周遊了這個url中的兩個級别。一級是教育訓練師,第二級是教育訓練師提供的教育訓練。

我們應該穿越多少級别?這是一個很難回答的問題,但是最好将它保持在最多三個級别,除非商業案例要求越高。

4 複雜性

強烈建議使用查詢字元串來降低具有多個不同關聯的url的複雜性。以下顯示了如何使用對使用者有點複雜和不直覺的查詢字元串:

get / trainers / 12 / training / 11 / zip / 75080 / city / richardson / state / tx

以下顯示了更好的方式來編寫查詢字元串:

get / trainers / 12 / training / 11?zip = 75080&city = richardson&state = tx

什麼進入查詢字元串?沒有硬而快的規則。您可以使用域驅動設計方法将實體放在查詢字元串(在本例中為“教育訓練者”和“教育訓練”)之前的正常url中,并将值對象作為查詢字元串的一部分添加(在這種情況下)郵政編碼,城市和州)。雖然值對象類似于域驅動設計中的實體,但它們可能沒有與其相關聯的id。在這種情況下,位址是一個值對象,假設我們的位址沒有id,那麼該值對象的屬性可以成為查詢字元串的過濾條件。

這是普遍的法律嗎?

不,這不對。這種技術可以在通用情況下有所幫助。但是,通常您的業務決定了過濾條件,但這是您可以偏離的。

我建議在url中的父子關系中最多可以分三個級别。如果您的網址仍然很複雜,請考慮添加一個查詢字元串。

5 錯誤格式

當我們沒有明确定義格式時,錯誤格式化可能變得非常有趣。我認為一個錯誤格式是非常重要的,并且需要在公司中全面地具有特定的錯誤格式。讓我們考慮一個錯誤格式,如下所示:

{

“error_type”:“應用程式錯誤”,

“error_details”:“#500:内部伺服器錯誤”

}

雖然這不是一個錯誤的錯誤格式,但有點難以使用。從用戶端的角度來看,http錯誤代碼不是一個不同的字段,需要通過在“:”級别分割字元串“error_details”,然後将其與所有可能的http代碼進行比較來推斷。在用戶端級别有空間的錯誤和處理是不必要的和不需要的。這是我喜歡的另一種錯誤格式:

“http_code”:“401”,

“message”:“需要驗證”,

“internal_error_code”:“123”,

“details_url”:http:// chanderdhall.com/wiki/errors/123

諸如“internal_error_code”等屬性名稱可以縮短,如“代碼”。這些屬性名稱更長的原因是為了使它們也是不言自明的。在上面的示例中,401隻是http錯誤代碼,123是一個内部錯誤代碼詳細資訊,可以在details_url找到。這有一個額外的優勢,使使用者更好地了解錯誤。

關于應該支援多少個http錯誤代碼,這取決于你。約10個标準代碼應該是足夠的。我的建議是使用http錯誤代碼,使其符合标準。每當我們看到一個200錯誤,那麼我們知道我們是成功的,是以api的使用者知道關聯的http錯誤代碼是典型的。

希望您喜歡api設計的最佳實踐第1部分。如果您有任何問題,請給我發電子郵件,請通知我。在第2部分中,我們讨論版本控制,分頁,部分響應,格式化結果,多個響應,搜尋和超媒體。

随時通路我的部落格相關文章。

繼續閱讀