轉載自公眾號碼農有道

我們有個銀行

想想一下你正在經營一家銀行,是不是想想都很激動了,YY無罪哈。

銀行裏有一個很堅固的保險庫(Vault)用來存放錢,還有一個賬本(Logbook)記錄客人金額數目。運作這個銀行有一個非常簡單(懶惰)的方法:給每個來訪者開放一次訪問許可權,沒人去檢查來訪者的身份,銀行相信人們會做出正確的操作。

在這個開放的銀行,客戶想要存錢,需要做的步驟如下:

1:拿錢去銀行;

2:打開保險庫,把錢放中間;

3:在賬本上寫上一條記錄:我是xxx,我存了xxx錢;

4:離開銀行。

很顯然,聰明的你肯定不會用這個方法管理你的銀行,因為這個方法存在下面兩個問題:

1:保險庫的門很難開,需要一定的體力。對弱勢羣體不是很友好,這可能違反了一些健康和安全的規定。同樣,有人手部受傷,或者眼睛看不清,就無法在賬本上讀寫。

2:在這個方法中,銀行相信人們是絕對誠實的。顯然,現實中總有那麼些不誠實的人。我打賭有人會存 100 塊,然後在賬本上寫存了 10000 塊。沒兩天你就破產了。

因此,我們需要進一步設計一個更為完善管理銀行的流程。

我們請了個銀行出納

既然自己完全放任不管會出現上面的問題,我們可以考慮僱傭一個聰敏強壯的人來處理所有的保險庫訪問,於是我們僱傭了櫃員Sally來進行這項工作。

現在,我們管理銀行的方式有了一定的改善了:有一堵牆(Sally)將保險庫和賬本與客戶分開,客人不可以直接在賬本或者保險庫操作,如果他們想要存款取款,就要通過我們的友好的櫃員莎莉。

現在客戶再想要存錢,需要的步驟複雜了一些,如下:

1:拿錢去銀行;

2:告訴櫃員Sally,我是xxx,我需要存xxx這麼多錢到我的賬戶;

3:Sally拿著你存放的錢放到保險櫃,她很強壯,很輕鬆做到這點;

4:Sally在賬本上記下這條記錄:xxx存了xxx這麼多錢;

4:Sally回到櫃檯,通知客人可以離開了;

4:客人離開銀行;

現在,客人不需要在打開那個龐大笨重的門了,整個流程對於客人來說沒有任何障礙。而Sally也是我們信任的人,因此上面存在的第二個問題風險也小多了。

API---應用編程介面

現在,我們可以介紹 API 的概念了。API 是稱為應用編程介面,就是軟體系統不同組成部分銜接的約定

簡單來講,API 允許你輕鬆地與其他軟體交流,這很重要。

在我們的比喻中,銀行有一個很難打開的保險庫大門。如果我們讓銀行櫃員開門,那麼客戶就不用費勁去開門,客戶節省時間,銀行也更安全。

同樣,我們抽象出操作的實現細節(例如分配系統內存,或向空間發射火箭),這將有助於降低程序員的認知負荷(一個人必須一次記住的東西的數量),從而提高生產力。例如,如果我們製作一個將火箭發射到太空的 API,程序員就可以使用這個 API,眨眼之間,引擎就會點燃,火箭就會直射天空。由於實現細節被抽象出來(隱藏在 API 的後面),我們的程序員不需要知道火箭科學就能將火箭送入太空。

有了這個信息摘要,還有另外一個好處:只要它們遵循相同的協議,組件就可以被換出(swap out)和替換(replace)。銀行不需要知道客戶是如何到達銀行的,客戶也不需要知道銀行已經把所有的錢都轉移到了避稅天堂。只要銀行櫃員還在那裡,知道如何取錢,整個交易所將繼續進行。

API 無處不在:從操作系統裏的簡單fork()到複雜的 API(如 Google Maps API),他們都在這裡讓程序員更輕鬆。

銀行裏有什麼

再來看看我們的銀行。

你可能注意到了,銀行有兩部分:前部區域,客戶有序的排隊;後部區域,處理貨幣。在中間的櫃檯,那前後區域被隔離。互動只能發生在中間櫃檯上的窗口(Sally)。

在 API 術語中,我們城中間區域為 Interface;這是軟體組件交互的地方。在我們的銀行,前臺後臺都知道這個地方的存在,也都同意在這裡交換信息。

現在,假設鮑勃來取錢。鮑勃在櫃檯說「嗨,我是鮑勃,我可以從我賬戶上取走 500 美元麼?」

銀行櫃員說「當然可以,請稍等。」

莉莎很清楚如何取錢,然後拿到錢給了鮑勃「這是你的錢,謝謝,再見。」

有一次,鮑勃喝 high 了,又來了銀行,他問櫃員莉莎「庫裏這個賽季的 2 分命中率為什麼提高到了 59%?」

作為銀行櫃員且壓根不看籃球的莉莎一臉懵逼。

在 API 術語中,協議是定義組件如何相互交互的一組規則。雙方都必須理解和堅持同樣的溝通協議才能成功。在這種情況下,銀行櫃員理解提款和存款,但她並不理解籃球。

莉莎和鮑勃交流都用普通話,我們稱其為格式:它指定如何編碼要發送給對方的數據。換句話說,這裡的通訊格式是普通話。與協議一樣,雙方都要理解和堅持這一個是,如果鮑勃覺得自己的廣東話很炫酷,對莉莎說「我想撳五百蚊出嚟呀唔該」(我想拿出五百塊謝謝)。由於莉莎聽不懂所以無法做出任何的操作,信息交換就失敗了。

在現實世界中,Web API 的常見格式包括 XML 和 JSON,儘管 JSON 在很流行,因為它比XML 輕而易讀,而 XML 在 Java 世界中仍然佔據重要的位置,特別是企業級(例如,在 SOAP 中進行會話的 API)。對於需要交換大量數據(特別是多人遊戲)的應用,像ProtoBuf和MsgPack這樣的二進位協議經常被用來節省空間並提高編碼/解碼的效率。

最後,我們假設我們也想把業務拓展到股票市場。我們需要一個特殊的銀行出納員來處理股市交易。我們稱這個新的股票交易員湯姆:

在 API 術語中,API 端點通常是指在同一個介面中提供特定功能子集的服務提供者。在這種情況下,Tom 和 Sally 都是端點。不同的端點可以有不同的協議和不同的格式。

總結一下:Interface 是不同軟體組件交互的地方。一個協議是一組定義它們之間如何相互作用的規則,以及格式定義它們是如何相互交談。端點在相同的介面內提供不同的功能。

銀行櫃員還能做什麼

現在我們介紹完 API 的一些基本概念了,再來聊聊 API 的一些常見功能。

這次鮑勃又來取錢了,他試圖取出 10000 美金。

櫃員在取錢給他之前,一定會查查他賬戶有沒有 10000 美元。API 可以包含驗證邏輯,以確保所有的操作都是合法的。

事實證明,鮑勃賬戶上只有 100美元。我們可以讓銀行櫃員告訴他資金不足。API 可以具有錯誤報告機制,來指示已經發生的錯誤。

鮑勃認為這肯定搞錯了,並要求銀行櫃員給出自己名下所有賬戶單據,以及他在每個賬戶中有多少錢。原來鮑勃有 200 個賬戶。一次給完他並不是很實際,所以櫃員莎莉一次向展示了 10 個賬戶。當鮑勃看完 10 個,他就可以繼續看下 10個。這就是所謂的分頁和分頁數據集,可以節省帶寬和伺服器資源,因為不需要一次獲取數據集中的所有內容。如果鮑勃只想知道賬戶餘額,而不是賬戶有多少獎勵積分,他可以要求莎莉只顯示餘額。這被稱為過濾,有助於節省帶寬和資源,並且更易於導航。

在檢查所有所有賬戶之後,鮑勃發現自己確實沒有 10000 美元。但是他知道愛麗絲買了股票賺了大錢(圖6),所以他離開了銀行,過一會偽裝成愛麗絲又回到了銀行,他告訴櫃員莎莉「我是愛麗絲,我要取 10000 美元」。

我們讓莎莉在取錢之前要驗證客戶的身份和銀行卡,這種情況下,鮑勃沒有這些證明,只能灰溜溜的離開銀行。授權和訪問控制可以內置到一個 API 中,以確保只有經過授權的人員才能訪問特定的數據。

最後,在試圖取出 10000 美元失敗後,鮑勃氣急敗壞的返回銀行,每次只取出 0.01 美元(可能是為了報復莎莉)。如果莎莉做了,會耗時耗力。我們可以指定取錢的頻率,比如 10 分鐘只能取一次錢,如果鮑勃真想每次去 0.01 美元,那他要在銀行待上一段時間了。我們可以通過限速來控制伺服器的資源分配,保證用戶不會濫用服務。

API 與上述功能相結合,可以充當防火牆,保護資源不被誤用,同時允許合法的請求。

功能越大,責任越大

API 真是好東西,但是如果設計的不好,會讓開發者很難受,以下是我認為在設計 API 時一些有用的標準:

明確每個端點的作用:你的端點應該有基本的名字,且要清晰,言簡意賅。;

錯誤應該是清晰易懂的:告訴客戶他們在銀行裏沒有足夠的餘額是對的。告訴客戶發生了「錯誤#506340」,那就讓人摸不清頭腦了。儘管通過返回一個錯誤代碼來保存幾百個位元組的數據可能是很有吸引力的,但事實上,這隻會阻礙客戶選擇你的銀行;

記錄一切:這是非常重要的,如果你希望你的開發者每次遇到錯誤時都不要把頭髮拉出來。給他們充分的支持,清晰,簡潔的記錄。

保持一致:如果 API 的某些端點和其他的不同,那麼你用戶在 Deadline 之前會瘋狂 Google 搜索(順便噴你)。確保你的命名規則,錯誤處理和其他行為在所有端點上保持一致;

多聽取反饋:想想開發人員將如何使用你的 API,並確保它儘可能簡單直觀。

--THE END--

技術交流可以加個人威信13266630429,驗證:知乎

公眾號baiwenkeji


推薦閱讀:
相關文章