技術探索-從全棧到雙棧

目前項目開發中, 后端主要使用Spring Data Rest, 前端嘗試過基于Vue和Bulma的單頁模板vue-admin, 由于Bulma相對比較新, 成熟的組件庫少. 后來引入了開源模板renren-security, 包含了用戶, 組織和權限管理的基本功能, 代碼結構較為簡單, 前端使用了Vue, 也保留了傳統組件, 便于模塊間解耦和兼容舊頁面. 為便于開發, 把前端改為前后端分離的多頁應用, 參考了renren-fastplusjeefast, 原項目前端與后端耦合并不多, 改動之處主要是使用了token認證替換了session認證, 并且把權限字符串發送到前端判斷.(因此在后端需要認證權限, 否則可能會有偽造的請求) 另外使用了通用組件處理CRUD的公共功能d2-crud. 該組件最初取自D2項目團隊D2 Projects, 開始關注該項目是由于在飛冰上看到他們發布的Vue項目腳手架, 有一套相關的項目, 形成了自己的小生態. 我一直認為有潛力的項目會重視生態建設, 但是他們的整體項目仍是單頁模板, 難于和舊代碼集成, 所以只用了CRUD組件. 當時該組件還處于開發初期, 代碼較簡單, 但作者是個人開發, 需要的一些功能等不及, 所以自己做了表格和表單組件的拆分, 引入了spring-data-rest-js與后端通信, 使用了AlaSQL在前端進行數據緩存和導入導出. 對于數據表之間的關聯也在前端實現.

這一套工具組合起來, 簡單的增刪改查頁面開發效率還可以, 基本不需要寫代碼, 每個模塊只需要后端寫好實體類, 前端建立數據配置, 建好相應的頁面, 配好菜單路徑和權限, 就可以使用了. 特定的需求可以在前端添加按鈕和函數, 原則上不需要在后端修改.

目前感覺到開發中存在的問題:
Spring Data Rest功能較弱, 不能方便的實現復雜查詢. 目前是通過把數據一次全部加載到前端, 在前端進行查詢處理. 后期還是要考慮通過后端接口查詢, 需要引入新的實現方式.
前端組件標準化不夠. 通過不同場景下的使用需求可以提煉出一些前端通用的需求, 為了避免代碼重復做了一些組件封裝, 但是只是粗略實現了基本功能, 不夠清晰簡潔.
需要手工對接的地方還是較多, 需要按照前端和后端的技術需要去適配同一個業務需求. 未來需要整理業務中通用的需求, 模式, 形成通用的聲明化配置化的代碼基礎, 方便后續的開發.

所以接下來, 準備使用PostgreSql數據庫替換Mysql, 經調查測試, 其在性能和功能方面都更優秀. 然后可以使用PostgREST提供Http接口, 避免了手工維護后端接口, 前端在權限范圍內可按需操作后端數據. 權限判斷等必須在后端完成的功能通過在數據庫中聲明, 簡化了開發, 也保證了數據的完整性. 關于這種后端自動生成接口的技術, 其實一直在關注. 原則上后端的很多工作就是把數據庫的訪問轉成HTTP的接口, 這種工作應該自動完成更好. 如果數據庫沒法直接提供HTTP形式的接口(比如像CouchDB那樣), 那么最好是只通過一層簡單的封裝, 對外暴露Web接口. 這方面目前感覺做的最成熟的就是PostgREST. 以前一直使用的是Spring Data Rest, 只提供了最簡單的CRUD和分頁功能, 并且需要Spring環境. 在后端只提供數據接口的情況下, 顯得結構復雜, 功能單薄. github上有人建了一個列表automatic-api, 總體來看這方面的技術多數是小規模的探索, 沒有形成整體的開發架構. 最近看到國內也有人在做這種嘗試APIJSON. 這種思想和實現并不是很難, 和所有的ORM或數據訪問框架一樣, 都是拼SQL語句. 關鍵是要形成完整的開發模型, 需要一套相關項目和工具組成的生態系統. 其中首先要解決的是權限控制問題. 很多人說, 前端直接傳SQL語句到后端執行最簡單了, 但是不解決授權驗證的問題, 就只能作為原型技術來用. PostgREST利用了PostgreSql數據庫本身強大的權限管理和編程功能, 利用JWT傳遞權限角色到數據庫, 所有的授權判斷直接利用數據庫本身的管理功能. 最大化的減少了代碼的冗余, 也保證了用于生產環境的規范化. 原則上, 只要是權限范圍內的操作都可以在前端執行, 后端不需要寫業務相關代碼. 當然, 如果需要寫的話, 可以在數據庫中寫存儲過程(函數), 前端通過Web接口調用. 這樣的技術架構實際上把項目整體簡化成了最為本質的兩層: 數據 和 界面. 這是軟件的本質功能, 其余所有的環節都屬于中間步驟, 可以被簡化, 規范化和通用化. 這是最初和最終的目標, 參見第一篇文章.

至于這種模式存在的問題, 首先是最好把數據協議和傳輸協議分開, 雖然現在HTTP是Web標準, 但是面向未來, 最好不要捆綁在特定的傳輸協議上, 只做好Web可用的數據訪問接口, 底層使用websocket, 或者HTTP2, HTTP3, 或者別的什么協議都可以. 這個問題其實是由于TCP/IP協議簡化的應用層造成的, OSI模型中的會話層和表示層是有必要的, 而且并不需要特殊硬件, 應該是在軟件中分層. 把所有功能都簡化到應用層的后果就是HTTP承擔了太多角色, 沒有一個清晰的層次, 導致了Web開發需要后端寫很多難以復用的接口. 所以REST和GraphQL都在填這個坑, 我覺得最根本的方式還是重視OSI模型, 在軟件架構中分離出會話和表示層, 建立起通用規范的實現和接口調用方式, 這樣不僅對于Web, 對于更底層直接基于socket的調用都是大有好處的, 現在的情況下是這些功能分布于通訊框架和業務代碼中, 沒有一個清晰的結構, 增加了復雜性. 當然, 這是從長遠和理想角度考慮, 目前HTTP接口還是夠用的, 前端通過對應的客戶端庫轉接相應格式的接口, 后續切換應該也問題不大.
其次是綁定了特定數據庫的問題, 這個問題目前看來并沒有太好的解決方式. 數據庫領域的分裂割據跟操作系統, 瀏覽器, 編程語言一樣, 由來已久, 短期難以消除. 如果我們想只用標準SQL, 使用各個數據庫通用的部分, 那么最好能像在前端一樣, 用jQuery這樣的庫處理瀏覽器差異, 但是目前看來沒有哪個項目能承擔起這個重任. 從中小企業的需求和現狀來看, 大部分使用數據庫只是簡單的數據存儲, MySQL也能滿足要求. 但是MySQL也有很多歷史遺留的和現實的問題, 功能偏弱, 不能統一. 目前看分裂有可能越來越大, 官方的MySQL8加入了角色管理, 但是社區很多已經轉向了MariaDB, 未來發展方向并不明朗. 而PostgreSql雖然顯得相對低調, 近幾年卻也呈現一路上升之勢. 加上一大批相關項目的支持, 未來成為數據庫領域的Chrome也未可知. 畢竟, 如果開源軟件功能足夠強大, 生態足夠豐富, 大部分企業也不會錯過壓縮成本的好機會.
另外, 關于數據庫內置的權限系統能不能很好的滿足業務特定的需求, 需要實踐驗證. 個人感覺確實是存在強耦合的風險. 目前的想法是, 讓業務角色和數據庫角色關聯, 發揮合力.

前端方面, 通用組件還需要繼續優化整理, 保證通用功能不出現重復代碼, 特定功能可以用簡潔的聲明式代碼實現. 在此基礎上加強前后端的整合, 屏蔽技術實現細節帶來的差異, 提煉出業務常用類型和流程, 比如人員, 機構, 日期時間, 貨幣, 任務, 單據. 更多的建立起基于業務的抽象, 業務類型決定了數據庫類型和前端組件類型. 對于簡單通用的需求, 只要聲明一次, 前后端都能夠以統一的方式成功運行. 對于特定的需求, 能夠在實際需要的地方(一般原則是權限范圍內的在前端, 需要控制權限的在后端)插入聲明代碼, 即可運行. 并且爭取做到用戶可以簡單的理解和配置, 在無需改動代碼和開發人員不參與的情況下實現系統按需修改.

最終的目標是希望真正能實現業務和技術的解耦. 業務規則應該是數據化, 聲明化的. 框架解析業務規則, 并產生能夠在計算機上運行的程序. 業務的變化不需要修改技術實現代碼, 技術的迭代也不會影響業務的正確運行. 這是軟件開發的長遠目標, 也是降低軟件復雜性和開發維護成本的根本方式. 結合當前的技術情況, 具體形式采用DSL, 還是SQL, XML或LISP, 或者干脆用規則表, 現在不能確定, 但總的思路是業務是數據, 就像函數是數據一樣. 聲明式的業務規則在底層框架的支持下自動轉換成程序在計算機上運行. 技術和業務的復雜性相互獨立. 開發人員的主要精力應該是理解業務需求, 設計合適的數據庫和界面, 并以聲明的方式直白的翻譯業務需求. 開發的難度大大降低, 無經驗的人員, 甚至客戶企業工作人員簡單熟悉后都可以參與開發, 把軟件的控制權交給用戶. 而專業技術人員更多的是負責保證底層環境的穩定運行, 實際上就是現在的云模式.

希望在不遠的將來, 碼農, 996, 軟件培訓這些概念會像舊時的黃包車, 西洋景, 大哥大, BP機一樣, 成為一種模糊的回憶. 生活在一個改變的年代, 我們都在努力奔跑的同時, 也享受著別人的努力所帶來的便捷.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容