偉大的 Web API 設計的 5 條黃金法則

已發表: 2022-03-11

有沒有發現自己想知道“他們在想什麼?” 當通過其 API 集成 Web 服務時? 如果沒有,你比我幸運得多。

任何軟件開發人員都知道讓項目演變成意大利麵條式代碼是多麼容易,而且 Web API 也同樣容易導致網絡錯綜複雜。 但它不需要是這樣的。 事實上,有可能設計出人們會真正喜歡使用並且您也會喜歡創建的優秀Web API。 但是怎麼做? 這個問題的答案就是這篇文章的全部內容。

看法

大多數情況下,當您構建解決方案時,您是在為非程序員或一般技術不成熟的最終用戶進行設計。 你為他們提供了一個圖形界面,如果你的工作做得很好,你已經從他們那裡收集到了一個很好的想法,即他們需要這個界面來做什麼。

但 API 開發不同。 您正在為程序員設計一個界面,可能甚至不知道他們是誰。 不管他們是誰,他們都會有技術成熟度(或者至少會認為他們有技術成熟度)來指出你軟件中的每一個小缺陷。 您的用戶可能會像您對他們的 API 一樣批評您的 API,並且會非常喜歡批評它。

順便說一句,其中有部分諷刺意味。 如果有人應該了解如何製作易於使用的 Web API,那就是。 畢竟,你和你的 API 的用戶一樣是一名軟件工程師,所以你分享他們的觀點。 不是嗎?

好吧,雖然您當然了解他們的觀點,但您不一定同意他們的觀點。 當您開發或增強 API 時,擁有 API設計者的視角,而他們擁有 API用戶的視角。

API 設計人員通常關注諸如“此服務需要做什麼?”之類的問題。 或“這項服務需要提供什麼?” ,而API 用戶則專注於“我如何使用這個 API 來做我需要的事情?” ,或者更準確地說, “我怎樣才能花最少的精力從這個 API 中得到我需要的東西?” .

這些不同的問題導致了兩種截然不同的觀點。 因此,設計出色API 的必要先決條件是將您的視角從 API 設計者的視角轉變為 API 用戶的視角。 換句話說,不斷問自己如果你是自己的用戶自然會問的問題。 與其考慮你的 API能做什麼,不如想想它可能需要或想要使用的不同方式,然後專注於讓 API 的用戶盡可能輕鬆地完成這些任務。

雖然這聽起來簡單明了,但令人驚訝的是 API 很少以這種方式設計。 想想你在職業生涯中遇到的 API。 它們在設計時似乎考慮到這種觀點的頻率如何? Web API 設計可能具有挑戰性。

話雖如此,讓我們繼續討論設計出色 Web API 的 5 條黃金法則,即:

  1. 文檔
  2. 穩定性和一致性
  3. 靈活性
  4. 安全
  5. 易於採用
相關:使用 REST 規範你從未做過的 5 件事

規則 1:文檔

文檔。 是的,我從這裡開始。

你討厭文檔嗎? 好吧,我可以理解,但戴上你的“用戶視角”帽子,我敢打賭,除了編寫文檔之外,你最討厭的一件事就是不得不嘗試使用未記錄的 API。 我休息一下。

底線是,如果您希望任何人使用您的 API,文檔是必不可少的。 你只需要把這件事做好。 這是用戶首先看到的東西,所以在某些方面它就像禮品包裝。 呈現得好,人們更有可能使用你的 API 並忍受任何特質。

那麼我們如何編寫好的文檔呢?

相對簡單的部分是記錄 API 方法本身; 即,示例請求和響應,以及兩者中每個元素的描述。 幸運的是,有越來越多的軟件工具可以促進和簡化生成文檔的任務。 或者您可以自己編寫一些東西來內省您的 API、端點和函數,並為您生成相應的文檔。

但是,優秀文檔與充足文檔的區別在於包含使用示例,理想情況下,還包含教程。 這可以幫助用戶了解您的 API 以及從哪裡開始。 它引導他們並幫助他們將您的 API 加載到他們的大腦中。

例如,如果 Twilio 的開發人員要列出對其 API 的每個類、每個方法和每個可能的響應,但沒有提及您可以通過以下方式發送 SMS、跟踪呼叫或購買電話號碼他們的 API,API 用戶需要很長時間才能找到該信息並有凝聚力地理解它。 你能想像對一棵巨大的類和方法樹進行排序,而不知道它們的用途,除了它們的名字嗎? 聽起來很可怕吧? 但這正是許多 API 提供者所做的,因此他們的 API 對任何人來說都是不透明的,除了他們自己。 Rackspace CloudFiles 開發人員和 API 指南就是這樣一個例子; 除非您已經了解他們在做什麼以及他們在提供什麼,否則很難掌握方向。

因此,編寫簡明的教程,幫助開發人員快速啟動和運行,至少包含他們正在嘗試做的事情的框架,然後將他們指向更詳細、完整記錄的功能列表的方向,以便他們可以擴展關於他們所擁有的。

完成文檔後,請務必驗證它對您以外的其他人是否有意義。 將其發送給您網絡中的其他開發人員,除了將他們指向文檔外,不給他們任何指示,並要求他們按照教程或在大約 15 分鐘內構建一些非常基本的東西。 如果他們無法在 15 分鐘內與您的 API 進行基本集成,那麼您還有更多工作要做。

有關優秀且詳細的文檔的一些值得注意的示例,請查看 Twilio、Django 和 MailChimp。 這些產品都不一定是其市場中最好的(儘管它們都是好產品),但它們確實通過在其市場中提供一些最好的文檔來區分自己,這無疑促進了它們的廣泛接受和市場份額。

規則 2:穩定性和一致性

如果您曾經使用過 Facebook 的 API,您就會知道他們棄用和完全重寫其 API 的頻率。 無論您多麼尊重他們的黑客文化或他們的產品,他們的觀點都不是對開發人員友好的。 他們仍然成功的原因是他們有十億用戶,而不是因為他們的 API 很棒。

但是您可能沒有如此龐大的用戶群和市場份額,因此您將需要一個波動性小得多的 API,讓舊版本在相當長的一段時間內保持運行和支持。 甚至可能幾年。 因此,為此,這裡有一些提示和技巧。

例如,假設您的 API 可通過 URL http://myapisite.com/api/widgets訪問,並以 JSON 格式提供其響應。 雖然乍一看這似乎很好,但當您需要修改 JSON 響應的格式時會發生什麼? 已經與你融為一體的每個人都會崩潰。 哎呀。

所以提前做一些計劃,從一開始就對你的 API 進行版本化,明確地將版本號合併到 URL 中(例如, http://myapisite.com/api/widgets?version=1 ://myapisite.com/api/widgets?version=1 或http://myapisite.com/api/widgets/v1 ),這樣人們就可以依賴版本 1 工作,並且可以在準備好升級到任何後續版本時進行升級。 如果您需要在某個時候逐步淘汰之前的版本,請繼續,但要給予充分的通知並提供某種過渡計劃。

一個好的 URL 方案將在 URL 中包含主要版本。 對輸出格式或支持的數據類型的任何更改都應導致升級到新的主要版本。 通常,如果您所做的只是將鍵或節點添加到輸出中,則保持相同的版本是可以接受的,但為了安全起見,任何時候輸出更改時,都會更新一個版本。

除了隨著時間的推移保持穩定之外,API 還需要在內部保持一致。 我見過許多 API 會根據所使用的端點更改參數名稱或 POSTing 數據的方法。 相反,您應該在 API 中全局處理通用參數,並使用繼承或共享架構在整個 API 中一致地重用相同的命名約定和數據處理。

最後,您需要記錄並發布變更日誌以顯示 API 版本之間的差異,以便用戶準確了解如何升級。

相關: Grape Gem 教程:如何在 Ruby 中構建類似 REST 的 API

規則 3:靈活性

垃圾進垃圾出 (GIGO) 是大多數程序員眾所周知的口頭禪。 應用於 Web API 設計時,該指導原則傾向於規定一種相當嚴格的請求驗證方法。 聽起來不錯,對吧? 沒有混亂,沒有問題。

然而,與所有事情一樣,需要有一些平衡。 由於無法預測用戶希望使用您的服務的每一種方式,並且由於並非每個客戶端平台都是一致的(即,並非每個平台都具有非常好的 JSON 支持、體面的 OAuth 庫等),因此最好對於您的輸入和輸出約束,至少具有一定程度的靈活性或容忍度。

例如,許多 API 將支持各種輸出格式,如 JSON、YAML、XML 等。 al.,但僅支持在 URL 本身中指定格式。 本著保持靈活性的精神,您可以允許在 URL 中指定它(例如/api/v1/widgets.json ),或者您也可以讀取並識別Accept: application/json HTTP 標頭,或支持查詢字符串變量,例如?format=JSON等。

當我們這樣做的時候,為什麼不允許指定的格式不區分大小寫,所以用戶也可以指定?format=json呢? 這是減輕 API 用戶不必要的挫敗感的經典示例。

另一個例子是允許輸入變量的不同方式。 因此,就像您有多種輸出格式一樣,也允許多種輸入格式(例如,純 POST 變量、JSON、XML 等)。 您至少應該支持標準 POST 變量,並且許多現代應用程序也支持 JSON,因此這兩個是一個很好的起點。

這裡的重點是你不應該假設每個人都分享你的技術偏好。 通過對其他 API 的工作原理進行一些研究,並通過與其他開發人員的對話,您可以收集其他有用的有價值的替代方案並將它們包含在您的 API 中。

規則 4:安全

安全性顯然是構建到您的 Web 服務中的最重要的事情之一,但是如此多的開發人員使得它非常難以使用。 作為 API 提供者,您應該提供在訪問 API 時如何進行身份驗證和授權的可用示例。 這應該不是最終用戶花費數小時處理的難題。 讓他們成為您的目標,即他們要么不必編寫任何代碼,要么只需不到 5 分鐘即可編寫代碼。

對於大多數 API,我更喜歡簡單的基於令牌的身份驗證,其中令牌是分配給用戶的隨機哈希,如果它被盜,他們可以隨時重置它。 允許通過 POST 或 HTTP 標頭傳入令牌。 例如,用戶可以(並且應該)將 SHA-1 令牌作為 POST 變量發送,或者作為“授權:da39a3ee5e6b4b0d3255bfef95601890afd80709”等格式的標頭髮送。

此外,請選擇安全令牌,而不是簡短的數字標識符。 不可逆的東西是最好的。 例如,在用戶創建期間生成一個 SHA 令牌並將其存儲在數據庫中是相對簡單的。 然後,您可以簡單地在數據庫中查詢與該令牌匹配的任何用戶。 您還可以使用唯一標識符和鹽值生成令牌,例如SHA(User.ID + "abcd123") ,然後查詢匹配的任何用戶; 例如, where TokenFromPost = SHA(User.ID + "abcd123")

另一個非常好的選擇是 OAuth 2 + SSL。 無論如何,您都應該使用 SSL,但 OAuth 2 在服務器端實現起來相當簡單,並且庫可用於許多常見的編程語言。

如果您創建的 API 應該可以通過 JavaScript 在公共網站上訪問,您還需要確保為令牌驗證每個帳戶的 URL 列表。 這樣,沒有人可以檢查對您的 API 的調用,從您的用戶那裡竊取令牌,然後自己使用它。

以下是其他一些需要牢記的重要事項:

  • 白名單功能。 API 通常允許您對數據執行基本的創建、讀取、更新和刪除操作。 但是您不想對每個實體都允許這些操作,因此請確保每個實體都有一個允許操作的白名單。 例如,確保只有授權用戶才能運行/user/delete/<id>之類的命令。 同樣,在用戶請求中發送的所有有用標頭也需要根據白名單進行驗證。 如果您允許 Content-type 標頭,請驗證用戶發送的內容是否與支持的內容類型的 whilelist 相匹配。 如果不是,則發回一條錯誤消息,例如 406 Not Acceptable 響應。 白名單很重要,因為許多 API 是自動生成的,或者使用黑名單代替,這意味著您必須明確說明您想要什麼。 然而,安全的黃金法則是從零開始,只明確允許想要的。

  • 保護自己免受跨站點請求偽造 (CSRF)。 如果您允許會話或 cookie 身份驗證,則需要確保您保護自己免受 CSRF 攻擊。 開放 Web 應用程序安全項目 (OWASP) 提供了有關如何排除這些漏洞的有用指南。

  • 驗證對資源的訪問。 在每個請求中,您需要驗證用戶實際上是否被允許訪問他們所引用的特定項目。 因此,如果您有一個端點來查看用戶的信用卡詳細信息(例如/account/card/view/152423 ),請確保 ID“152423”引用的是用戶真正有權訪問的資源。

  • 驗證所有輸入。 來自用戶的所有輸入都需要安全解析,如果您使用 XML 或 JSON 等複雜輸入,最好使用知名庫。 不要構建自己的解析器,否則您將陷入痛苦的世界。

規則 5:易於採用

這確實是最重要的規則,並且建立在所有其他規則的基礎上。 正如我在文檔規則中提到的,請與不熟悉您的 API 的人一起嘗試。 確保他們至少可以在幾分鐘內啟動並運行您的 API 的基本實現,即使只是按照教程進行操作。 我認為15分鐘是一個很好的目標。

以下是一些簡化和促進 API 採用的具體建議:

  • 確保人們可以真正使用您的 API,並且每次都能第一次使用。 讓新人偶爾嘗試實現您的 API,以驗證它不會以某種您已經免疫的方式造成混淆。

  • 把事情簡單化。 不要做任何花哨的身份驗證。 不要做一些瘋狂的自定義 URL 方案。 不要重新發明 SOAP、JSON、REST 或任何東西。 盡可能使用已經實現並被廣泛接受的所有工具,這樣開發人員只需學習你的 API,而不是你的 API + 10 種晦澀難懂的新技術。

  • 提供特定於語言的庫以與您的服務交互。 有一些不錯的工具可以自動為您生成庫,例如 Alpaca 或 Apache Thrift。 目前 Alpaca 支持 Node、PHP、Python 和 Ruby。 Thrift 支持 C++、Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、JavaScript、Node.js、Smalltalk、OCaml、Delphi 等。

  • 簡化任何必要的註冊。 如果您不是在開發開源 API,或者如果有任何類型的註冊過程,請確保在註冊時,用戶會很快被引導到教程。 並使註冊過程完全自動化,無需您進行任何人工交互。

  • 提供出色的支持。 採用的一大障礙是缺乏支持。 您將如何處理和響應錯誤報告? 文件不清晰怎麼辦? 不成熟的用戶? 論壇、錯誤跟踪器和電子郵件支持是很好的開始,但請確保當有人發布錯誤時,您確實解決了它。 沒有人願意看到一個鬼城論壇或尚未解決的大量錯誤列表。

Web API 總結

Web 服務及其 API 比比皆是。 不幸的是,絕大多數都難以使用。 原因包括糟糕的設計、缺乏文檔、不穩定、未解決的錯誤,或者在某些情況下,以上所有。

遵循本文中的指導將有助於確保您的 Web API 乾淨、有據可查且易於使用。 這樣的 API 確實很少見,因此更有可能被廣泛採用和使用。

相關:逆向工程軟件私有 API 的教程:破解你的沙發