API 設計的最佳實踐
優秀的API設計話題,在很多團隊涌現,這些團隊正在努力完善他們的API策略。
在之前發布的博客上,我簡要的討論了API設計的重要性。一個設計良好的API應該包含那些好處:你的API應該能提高開發者經驗、方便的快捷文檔和高可用性。
但優秀的API設計究竟應該怎么做?在這個博客中,我將詳細的介紹一些RESTful API的***設計。
一個設計良好的API的特點
一般來說,一個有效的API設計遇有以下特點:
- 易于閱讀和使用。一個設計良好的API應該很容易被使用,其資源和相關操作能夠快速的被使用它的開發人員記憶。
- 難以誤用。設計良好的API實現和集成將是個簡單的過程,寫出錯誤代碼將變得不太可能。沒有嚴格按照API開發指南的終端用戶將會得到詳實的信息反饋。
- 完整又簡潔. ***,一個完整的API應該具有成熟的應用防止你的數據被泄露。API完整性會隨著時間的推移而改變,大多數的API設計人員和開發人員都應在現有基礎上逐步構建新的API。這是每一個使用API的工程師或公司都必須堅持的理念。
為說明下面列出的概念, 我會以一個照片分享的應用程序舉例。 該應用程序允許用戶上傳照片, 以拍攝地點和心情標簽描述照片特征。
集合,資源及其網址
了解資源和集合
資源是REST概念的基礎。 一條資源是一個重要對象,它本身可以被引用。 一條資源含有數據,與其他資源的關系,以及操作方法,以允許訪問和處理相關信息。
一組資源被稱為一個集合。 集合和資源的內容取決于你的組織和消費者的需求。 例如,如果你認為,市場獲得了你的產品用戶群的基本信息會受益, 那么,你就可以將此作為集合或資源。
統一資源定位器(URL)確定了資源的在線位置。 URL指向你API資源存在的位置。 基URL是這個位置的一致部分。
在照片分享應用一例中, 我們可以公開用戶數據,只要用戶通過集合和資源使用該應用程序, 經由適當的URL訪問。
- /users:用戶的集合。
- /users/username1:一個特定用戶的信息資源。
名詞化的URL更好
URL應該是整潔、優雅和簡單的,這樣開發人員更易在他們的web程序中使用你的產品。 很長且難以理解的URL不僅看起來很糟糕,而且在記錄時容易出現錯誤。所以使用名詞應該是很好的。
沒有規定讓資源名詞使用單數或復數,但是在如果是集合的話使用復數無疑很好的。 具有相似的資源和集合分別保持它們的一致性是較好的做法。
保持這些名詞的自解釋性,有助于開發人員了解從URL描述的資源, 這最終會使他們使用你的API。
回到照片分享應用程序,它擁有返回集合的公共API /users 、/photos。注意到它們都是復數名詞了嗎? 它們也是自描述的,我們可以推斷出 /users 和/photos分別是獲取產品注冊的用戶信息和分享的照片。
用HTTP方法來描述資源的功能
所有資源都有一組方法,可以對它們進行操作由該接口暴露的數據。
REStful APIs包含主要的HTTP方法,其良好的定義和獨立的功能能夠應對所有資源。這里是RESTful API里常用HTTP方法列表,這些方法定義CRUD如何操作資源和集合。

(如果你想了解PUT和PATCH的不同,可以到StackOverflow上看看這個)
雖然在URL中使用動詞也不錯,但是GET, PUT, POST, DELETE操作已經用于描述了資源的操作,因此在URL中使用動詞代替名詞會顯得比較混亂。
在照片分享app中,/users 和/photos 是一個端點,API的終端消費者可以更直觀的使用RESTful CRUD 進行上述的操作。
響應
提供反饋,以幫助開發人員成功
在他們使用你的產品時向開發人員提供良好的反饋,對于提升使用率和用戶維持率是很好的。每一個客戶端的請求和服務端的響應都可以看做是一個消息,在理想化的RESTful 生態系統中,這些消息必須是自描述的。
良好的反饋對于實現的驗證是積極的,錯誤實現產生的消息可以幫助用戶調試和糾正使用產品的不正確方式。對于API, 錯誤信息是使用API上下文的良好方式之一。
調整你的錯誤與標準HTTP代碼一致。客戶端引發的錯誤應該使用400類型錯誤,如果是服務端的錯誤應該使用500類型來響應。 一個對資源操作成功后應該返回一個200類型的響應。
有很多的響應代碼。想了解更多, 看看這個REST API教程.
一般來說,使用你的API時有三種可能就結果:
客戶端應用程序的行為是錯誤的(客戶端錯誤–4xx響應代碼)
API行為錯誤 (服務器錯誤- 5 xx響應代碼)
客戶端和API工作正常 (成功– 2xx響應代碼)
成功解決客戶使用你的API時遇到的問題將大大改善開發人員使用體驗和防止濫用API。 詳細描述這些錯誤,同時保持簡明和整潔。在錯誤消息中提供足夠的信息有助于用戶解決它們的問題,如果你覺得需要更加詳細的信息,***另寫文檔并在此處提供鏈接。
GET 響應例子
一個良好設計的API應該有響應示例,以明白是否成功調用了一個URL。響應示例應該簡單、簡潔和易于理解的。 一個好的經驗法則是:幫助開發人員在5秒內理解一個成功的響應。回到我們的照片分享應用,我們定義了 /users 和 /photos URL。 /users 應該易數組的形式提供所有注冊的用戶,并且包含用戶名稱和加入日期屬性。
你可以在Swagger(OpenAPI)中使用 API設計工具來定義你的API,詳述如下:
- responses:
- 200:
- description: Successfully returned information about users
- schema:
- type: array
- items:
- type: object
- properties:
- username:
- type: "string"
- example: "kesh92"
- created_time:
- type: "dateTime"
- example: "2010-01-12T05:23:19+0000"
注意數據類型和實例的每個響應項注釋,最終用戶期望的是一個成功的GET調用。成功響應后最終用戶將接收的JSON看起來如下:
- {
- “data”:[
- {
- “Username”:“example_user1”,
- “created_time":“2013-12-23T05:51:14+0000 ”
- },
- {
- “username”:“example_user2”,
- “created_time":“2015-3-19T17:51:15+0000 ”
- }
- ….
- ]
- }
如果用戶調用了這個方法,就應該獲得包含上述數據和一個說明正確調用了的200響應狀態碼。 同樣的,,一個不正確的調用應該產生適當的400 或500 響應狀態碼和其它相關信息,以幫助用戶更好地操作。
請求
優雅的處理復雜性
你試圖開放的數據包含大量的有利于用戶的屬性,這些屬性描述的基本資源和隔離特定信息,可以通過適當的方法來操作。
一個API應該努力提供完整的信息、數據和資源來幫助開發者以無縫的方式與之整合。
然而, 完整意味著對你的API考慮通用使用情況。可能會有許多這樣的關系和屬性,單獨為他們定義資源不是好的做法。
資源暴露的數據量也應考慮。如果你暴露得太多,這會對服務器產生消極的影響,特別是對于負載和性能。
上述情況和關系是在設計的API時需要重點考慮的因素,可以使用適當的參數來處理。你可以掃描查詢參數中limit參數來限制響應數據量,或者讓客戶端使用路徑參數來隔離數據。
以我們的照片分享應用作為示例。
它可以用于開發者獲取在特定位置和特定主題標簽中共享的所有照片的信息。 您可能還想要通過將每個 API 調用的結果數限制為 10,以減輕服務器負載。 如果最終用戶想要找到波士頓的所有照片,并使用 winter 標簽,則請求將是:
- GET /photos?location=boston&hashtag=winter&limit=10
注意現在的復雜性如何被簡化為一個與查詢參數的簡單關聯。如果您想根據客戶的請求提供特定用戶的信息,則調用:
- GET /users/kesh92
這里的 kesh92 是一個指定的用戶名,它會返回該用戶的地點和加入日期。
這只是朝著API完備性進行參數設計的幾種方式,可以幫助用戶更直觀的使用你的API。
***, 有疑問時,暫時離開它。如果你重新思考了某個資源或集合的功能,應該把它放入下一個迭代中。開發和維護API是一個持續的過程,等待正確的用戶反饋可以構建一個健壯的API,以幫助用戶以創造性的方式集成和開發應用程序。
API設計入門
沒有一個API設計方法能夠一勞永逸解決所有組織的問題。上述的建議僅僅是參考意見和建議,能否采用取決于你的用戶情況和需求。
一個API設計至關重要的主要原因是你的API能幫助到終端用戶,他們的需求就是貫穿你整個API設計的指明燈。