微服務 API 的設計與實作,來到第二篇。
圖片來源: https://www.freecodecamp.org/news/rest-api-best-practices-rest-endpoint-design-examples/
會有這篇,其實是有感現在講架構的文章太多了, 但是每個人看了同樣的文章, 最後實作出來的落差都很大啊。很多架構類的文章都是標竿大型系統的設計,不過還沒有對應經驗的人,看了這類文章是沒辦法從小規模的系統經驗,直接跨過那道鴻溝啊,所以往往有些看的多的人,在專案上拿捏不好設計的力道,不知不覺就做了過度的設計 (過度可能是超出期待太多,或是超出能力範圍太多都算)。因此我在講完架構的設計概念後,我都會希望能搭配實作的驗證,PoC 也好, MVP 也好,總之能夠真正用能運作的方式,把要解決的情境用你想的架構實際推演一次。架構實作一定是複雜的,有很多工程問題要解決,因此能否在這階段盡可能的排除非必要的實作,又能達到驗證的目的,就是抽象化能力的考驗了。Do the right thing 比 do the things right 同樣重要,但是不先看清楚 right thing 的話會讓你後面的 do the thing right 功虧一簣,因此有了這篇文章,來驗證上一篇我介紹的方法: 用狀態機來驅動 API 設計。
所以,第二篇的主軸,我決定把內容重心擺在理想的設計,該如何搭配成熟的技術實作出來? 架構師最難的課題就是做好技術選型。你必須在整體的系統內找到背後統一的脈絡,做到每個子系統之間的協作是具有一致性的,而不是單純的從各個領域挑出最酷的技術來用就好了。例如最常見是安全機制,要在跨服務協作的前提下,讓大家的安全機制都標準化才能互通。同樣的道理,除了安全機制,其他在 Logging 處理,Configuration 的處理,認證授權的管控等等都是一樣。這些設計必須貫通整個系統,從前台 (面對 enduser)、後台 (面對客戶的管理者 staff)、中台 (面對外部開發商與營運商本身 developer / operator) 、甚至面對內部的核心系統其他 (微) 服務等等情況都是。
這些都是微服務架構設計的難題啊,我在第一篇提到如何用狀態機來收斂你的設計 (不論你用甚麼方法分析,DDD 也好,UML 也好..),將設計與實作都能擺在狀態機上面用一樣的方式驗證。這篇,我想延續狀態機的想法,當你有了很好很收斂的設計之後,我想完整的用 .NET 的生態系走過這整個從設計到實作的過程,期待能兼顧商業需求、架構與工程的需求都能兼顧。這篇會牽涉到很多實作的細節,涵蓋實作一個完整功能的微服務必要的架構跟設計。
這次我直接破題了。我想寫一篇從 State Machine 的分析為主軸,來驅動整個服務的 API 設計的文章。
圖片來源: https://www.giga.de/artikel/was-ist-eine-api-schnell-erklaert/
“我們服務的 API 設計很糟糕,怎樣才能設計出好的 API? 有沒有一些 SOP 或是準則可以給我參考?”
其實這個問題我已經被問到爛了,答案當然是 “沒有” 啊 XDDD, 如果有的話,這個問題根本就不會是個難題,也不會有這 FAQ 了。首先,API 的好壞,”設計” 占了九成以上啊! 設計問題是沒有正確答案的,既然是設計,就是帶有個人風格的,你會發現有些大師的設計就是既精準又靈活,看的到背後的巧思,每個環節都搭配的恰到好處,找不出一絲多餘的設計。指南 (Guideline) 通常是告訴你該做什麼,不該做什麼。它可以讓你設計出及格的 API,但是沒辦法讓你設計出理想的 API。要達到這個境界 (我也還不夠格) 需要依靠的是對 domain 更精準的掌握…。
先定義一下,何謂 “好” 的 API? 我很看重 API 設計上的一致性。API 必須顧及很多層面,例如你要端出那些功能? 這些功能是否都用一樣的視角來設計? (主詞會不會一直變動?) 背後處理的邏輯是否一致? (某個 API 不准你取得的資訊,另一個 API 卻又可以?) 你能否在呼叫前就很明確的知道能不能這樣用? (還是任何大小事都要查文件才能搞懂?)
其實這些細節都很煩人啊! 這些都是很多不同面向的考量,我們在實作時同個面向的問題往往都能很一致的處理,不同面向的一致性往往就因為背後的實作階段不同,就很容易被忽略。因此我蠻重視在設計階段就先想辦法對齊這些不同面向的問題。我的作法是,通通都在狀態圖上面把這些 API 設計的要素標示出來,在同一張圖上面思考,就很容易在設計階段解決一致性問題。
繼上一篇文章: 刻意練習 - 打好基礎 講完整個我對技術人員職涯要持續成長,就必須要刻意的持續練習看法後,這篇我就來舉實際的案例吧。這篇案例是示範,當你學習了技術與管理的知識之後,如何融會貫通,運用在解決問題上的案例。你累積的經驗或是能力,若無法轉換為價值,那是沒有用的。技術人能展現的價值,就是解決問題。怎樣才能讓一個問題拿到你面前你都能迎刃而解? 最有用的就是連結你累積的各種能力。連結越強,織起來的知識網就越強韌,你看問題就會越到位。
這篇我就拿我在去年 91APP TechDay 以及 .NET Conf 2020 分享的主題: 維持非同步系統的 SLO 來當例子吧。這是近年來我擔任架構師,端出來的幾個 solution 之中,對於 “連結” 這件事最有代表性的案例了。這是個包含開發技術,架構設計,服務水準與流程管理等等層面的綜合需求。要解決這問題,你不但要有很札實的技術及實作能力、也要有很到位的 cloud infrastructure 掌控能力,同時還要具備管理知識,缺一不可,才有可能把這件事情解的漂亮。表面上看來,訂定服務水準要達成的目標 (SLO, Service Level Objective) 並落實,是個很純粹的技術題目啊,但是真正做過的人就知道,光是開規格就不知道該怎麼開了,團隊做出來你也很難驗證 (直到上線後碰到流量撐不住之後… )。
我在下半年的幾場公開演講,開始做了一點不同的嘗試。除了技術或是架構知識之外,我開始會強調為什麼會這樣思考的過程,也開始會帶到該怎麼培養這樣的經驗與能力的想法。在 2020 下半年,有幾場演講都往這個方向調整了。2020 下半年是個爆忙的半年,到現在終於有點力氣把這些內容整理一下了,於是就開了這系列文章 - 刻意練習。這篇是第一篇,主要就是對應到 2020/08 我在 Study4.Dev 八月份活動上分享的主題 - 後端工程師的修練之路。
最近一連串資安事件,加上這兩天看到圈子內很熱門的討論串 (大意: 服務開發商,到底該不該儲存能還原的使用者密碼),於是就想來寫點短篇一點的,說明一下我對軟體開發相關資安 issue 的看法。
那個討論串,我就不提供連結了。我的目的不是要把那位仁兄抓出來鞭,我只是要來聊聊這事件背後的看法而已。如果有人在底下留言附上 link, 我看到會刪掉的,先在此告知
其實我要談的,不是密碼該怎麼加密儲存 (encrypt),或是只儲存加鹽後的雜湊 (salt + hash) 這些技術問題,我想探討的是技術決策或架構設計者的原則跟態度問題。在軟體開發團隊內 (尤其是技術決策者),應該都要有正確的認知,不只是密碼儲存,而是泛指所有資安相關議題。如果你只把資安問題當作一種 “需求規格” 來看待,而非品質要求或是法規要求的話,一旦出事時真的會讓公司陷入困境的。