防止你的API被人採用的4個技巧

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"過去幾個月裏,我一直在對付一個流行健身品牌的API,最後發現自己陷入了一種卡夫卡式的噩夢。程序員都喜歡挑戰,優秀的程序員一定要征服種種挑戰。我一直覺得自己是一個非常優秀的程序員。因此,儘管每天晚上我都以失敗告終,只能上牀睡覺,但我內心深處的某些東西是不會讓我就此放棄的——第二天早上,我會帶着新的想法和新的動力滿血復活。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這樣的循環已經持續幾個月,這就像一場夢,日復一日,遲遲沒有甦醒的一刻。我要處理的任務很簡單:獲取數據,保存數據,完事。但面對這個API,我被一堆脆弱的代碼團團圍住,追逐着那些我永遠都抓不到的錯誤。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼,怎樣才能構建一個具備如此高技術障礙的API,讓你可以擊敗一個擁有20年經驗,過去總有辦法走出困境的老手呢?你如何讓他慢慢抓狂,並讓他從自己所熱愛的這一職業中獲得的所有快樂一掃而空呢。好吧,我會告訴你訣竅的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們先來佈置角鬥場地。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於授權需求,我們將使用"},{"type":"text","marks":[{"type":"strong"}],"text":"OAuth1a"},{"type":"text","text":"。當然,這是一個非常好的標準,但用它簽署請求會增加那麼一點點複雜性,讓你永遠沒法搞清楚原來是簽署導致請求失敗的。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"服務器到服務器的通信"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們不會響應你的API請求,而是給你回電。你請求服務器提供一些數據,然後在從現在到宇宙終結之前(或永遠不會)的某個時間點上,我們會做出迴應。響應一般需要幾毫秒,但有時需要幾分鐘,在極少數情況下需要幾個小時。但最重要的是,如果我們沒有任何數據,我們根本就不會做出響應。不一致是程序員的天敵。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這種設置在實踐中意味着什麼呢?這意味着你需要在服務器或代理後面設置一個端點。這也意味着在你的單元測試中,如果沒有響應,那麼你將不得不做一些工作。你得編寫一些代碼,對其進行測試,如果失敗還要檢查你的web服務器日誌。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,也許在你查看請求通過的那些日誌時,它終於有反應了,只不過響應來得慢一些。不過當然JSON沒有按照你預期的方式格式化,所以請重來一遍吧。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"禁止重複數據"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這招可是很不錯的。不管你請求任何數據,你都只能請求恰好一次。不是一分鐘一次,也不是一小時或一天一次——是這輩子都只能請求那麼一次。這實際上意味着任何單元測試都是不可重複的,想要重來一次?請手動註冊新帳戶並在裏面人工填好數據。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"假設當代碼生效時,一位用戶請求了某個時間段內的數據,他要的數據可能存在也可能不存在,你可能會,也可能不會收到這些數據,但你仍然需要跟蹤這一請求,因爲如果你這個請求只重疊了那麼區區一天,那麼在將來某個時候,你就會收到一條錯誤消息。當生產環境中的請求失敗時會發生什麼呢?當然沒有緩解措施,你什麼都做不了。這些數據是不可恢復的——永遠別指望它能恢復了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我可以用一整天談論這個技巧的強大力量。不過你只要簡單地想象一下,比如你編寫了自己的第一行代碼,然後又成功地執行了它,然後當你再次運行它時,它就沒有任何反應了。想象一下項目的其他部分全變成了這個樣子,那會是多麼壯觀的場面。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"開發和QA速率限制"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我想你可能會爭辯說,將QA速率限制設置爲遠低於生產環境的速率可能是有原因的。但如果將閾值設置爲每分鐘100天的數據(不是請求)會有什麼樣的結果呢?這個技巧特別狡猾。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先,它的確爲你的開發測試周期設置了一個最大閾值。你可以寫一些代碼,運行一個測試,然後開始等待。但它的要點在於它加入了另一個因素,讓代碼可能會莫名其妙地失敗。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最厲害的是當你正在嘗試開發一個高度可擴展的應用程序的時候,你到底該怎麼開始測試隨便什麼類型的負載呢?簡單的答案是你可以在生產環境中進行測試,也可以根本不做任何測試。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"PROD中的應用程序級別速率限制"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"應用程序級速率限制這個技巧的美妙之處在於,你需要一個消息隊列纔行。當然可能還有其他技巧,但如果它是一個Web應用,並且你不想讓一堆長時間運行的線程在隊列中運行,那麼這幾乎是你唯一的選擇。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當然,它們也加入了其他一些東西,但這些幾乎不值得一提,因爲這些東西只不過是典型的數據結構挑戰或糟糕的參數化選項而已。這些是你平日裏經常要面對的挑戰,並不是那些即便是最有經驗的開發人員也會屈服的挑戰。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在過去的幾個月裏,我花了很多時間試圖想象這個API背後的團隊究竟是什麼樣子的,以及他們到底有什麼樣的動機來開發這樣一個API。無論你是如何看待它的,他們的初衷肯定是防止別人使用這個API。也許,他們正在與一個其基礎設施擁有數十年曆史的系統交互,這一系統會因最輕微的干擾而崩潰。也許他們有很多新招來的開發人員,編寫了一些非常低效的代碼,而當他們探討解決方案的時候,最後想出來的辦法就是儘可能給用戶設置更多障礙?或者也許他們只是絲毫沒有同理心。也許當他們權衡設計決策時,可用性這一條的評分被減到了零,這樣其他所有問題就都能得到最大程度的重視了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但我認爲還有另一種可能。公司都喜歡把他們的花園圍起來,但在健身領域,數據可移植性是一個賣點。那麼,你如何才能同時實現兩者呢?你如何才能一邊把你的花園圈起來,與此同時給大家指出大門的位置呢?如果是因爲這樣的理由,這個開發噩夢就完全可以解釋清楚了。在這種情況下,認真努力地嘗試編寫代碼來使用它的用戶就是唯一的傻瓜。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文鏈接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https:\/\/chrislukic.com\/2021\/06\/16\/techniques-to-prevent-adoption-of-your-api\/"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章