Typescript前端接口联调自动化的探究与实践
源寶導讀:Web應用程序一般都是前后端分離的基本架構,而前后端很可能分別是兩撥人分別開發,前后端的接口連調成為高頻溝通的對象,開發內耗最大的也在這個環節。本文將分享如何基于OpenAPI將前后端接口協議標準化和自動化,從而大幅降低開發內耗。
一、背景
? 通常的前端開發中, 接口service層依靠人工閱讀接口文檔來手動書寫, 然而大部分工作是重復的, 骨架是相同的,只是接口數據和接口路徑等改變, 對于一個龐大的項目(比如接口數量幾百個), 并且客戶端存在多個情況下(比如h5和小程序還有android, IOS), 重復的勞動成倍增加, 而且維護起來也會非常麻煩和不可靠。
? 重復的工作是,后端開發人員開發了一套接口, ?前端開發又書寫了同樣一遍接口, 而且還要生成文檔, 而這些接口可以統一成一份與語言無關的結構化的描述, 前端可以利用code-gen自動生成可調用的service層。
? 而且對于現在基于Typescript前端的開發, ?接口協議生成的數據interface應該直接拿來使用, 用來約束各個業務模塊的數據結構, 如果要組合生成新的數據結構, 應該使用Typescript的高級類型來組合生成(比如Pick<>,Required<>, Partial<>, Omit<>), ?這樣前端的業務組件數據結構將和接口協議描述保持一致。
1.1 傳統前端后端聯調模式問題: 不可靠, 重復工作量, 低效
整個過程寫了兩份協議, 服務端一份, 客戶端一份, 工作重復。
聯調周期很長,并且需要不斷的重復溝通, B發布了一項接口參數更新, 需要通知C去查看文檔, 那么C有這么一個待辦事項, 什么時候執行大多數時候不得而知, 過了一段時間C查看了文檔之后發現有幾個地方不合理, 那么又通知B, 這樣聯調的周期又延時又低效。
令人忽視的一點是注釋, 同一個接口描述, 同一個參數的描述可能存在3種描述, 這可能讓團隊每個人對業務的理解都不一樣。
1.2 Typescript前端項目的特點
1.2.1 可使用豐富的高級派生類型
業務模塊中的子組件的數據結構一般是派生的子類型
當SampleInterface結構發生變化,派生的類型會自動繼承其中的屬性, 如果有沖突, ts會給出錯誤提示
1.2.2 開發過程數據結構優先
前端的業務模塊中:顯示, 交互等與用戶相關的功能操作都是圍繞數據來進行。
前端開發, 擴展, 維護和重構等工作也是圍繞數據來進行。
并且業務模塊的數據結構與接口的數據結構有很強的關聯性。
基于以上特點將數據結構定義來源單一化, 使業務數據定義更合理:
單一源化數據結構定義, 有利于統一維護, 利于重構。
當service接口數據結構發生變化, 那么派生的數據結構會自動適應, 如果有錯誤, 能夠根據Typescript語法提示完成重構, 最后再根據語法提示修改相關的業務相關的組件。
前端業務組件大部分數據結構與API接口的數據結構是關聯的。
能不能通過某種接口協議自動生成Typescript的接口定義呢?
Swagger Open API協議, ?protobuf協議等都是可以描述RESTFul API接口。
二、前后端聯調的優化解決方案: 以API協議為中心
按照之前的思路的理解: 特定的業務邏輯的數據結構在不同的業務組件中是高度一致的, 一個數據結構的定義應該只存在一份, 不應該手寫多份。
前后端維護唯一一個的規范來描述接口定義。
不同的客戶端語言可以根據這個協議生成可執行的接口。
2.1 步驟
2.1.1 基于Open API Specification (Swagger)協議的轉換研究
? OAS用來定義一個標準的, 與編程語言無關的RESTFul API的接口, ?可提供給計算機解析, 也可進行人工閱讀和分析, 是一種能結構化描述API接口的約定, 而目前主流的文檔生成工具都支持這種標準, 可實現個性化需求。
? OAP協議可以用JSON Schema來定義, 詳細可看:? https://swagger.io /specification /v2/
基本結構:
對應的Typescript示例:
2.1.2 生成Typescript目標代碼實際項目中的分析
? 命名空間根據項目的業務模塊來區分, 在Swagger協議中一般在tags里做為標記:
2.1.3 利用模板引擎mustache生成代碼
使用編程語言將原始的Swagger JSON轉換成更加直接并且有豐富變量的模板數據。
mustache模板是根據項目實際來設定, 靈活使用不同模板生成不同的目標代碼。
遇到少量 的特殊的接口, 可以過濾不生成, 然后手動實現接口即可。
具體項目在 https://github.com/mmmy/swagger-typescript-gen。
2.2 實踐結果
? 參考了一個nodejs的開源轉換工具, 修改增加了模板數據變量和模板:
Pulsar前端接口220+, code-gen生成了7000+行代碼。
dmp前端接口250+, code-gen生成了9000+行代碼。
? 后端生成的Swagger response中字段缺少必填屬性和枚舉屬性, 生成的接口相應Typescript數據結構都是可選參數。
? ?遇到的問題:類似遞歸的結構暫時無法生成:
? 遇到少量接口不能實現, 可以手動實現該接口。
? 不需要看api文檔, 卻能發現文檔的很多問題:接口定義了一個query參數 還有一個類型為json的body參數。
? 還有少量的接口未定義返回參數, 實際上有返回參數。
2.2.1 帶來的優勢
?一致性
? ? ? 前端的接口調用參數, 描述等任何信息將與協議一鍵同步。
?重構優勢
? ? ? 如果業務邏輯上接口發生變化, 將會自動影響相關的業務組件, 按照Typescirpt的提示能完成絕大部分工作。
?減少工作量
? 前端不需要再去查看API文檔, 手動同步書寫接口代碼, 后期維護也是維護源頭的協議。
三、結合Typescript開發模式進一步優化
? 假設所有的模塊都是具有完備的typescript設計和定義,為什么運行時還是會報語法錯誤, 類型錯誤?
? Javasctript本身是動態弱類型語言, 運行時并不能保證紅色箭頭輸入是合法的, 比如預期某個接口返回一個值為對象Object, 但是實際返回了一個null, 為了兼容, 不得不在每個組件中對很多值進行空值判斷, 來防止運行錯誤, 實際上不應該在B中做無意義的判斷, 因為在組件A中已經給了B正確的類型輸入, 正確的做法是處理和兼容紅色的輸入, 來確保輸入到A的值是合法的, 所以你對輸入數據不確定的代碼處才是問題的根本, 這和Tyepscript本身沒有關系。
3.1 在數據進入組件之前進行糾錯, 前端0錯誤成為可能
? 假設服務端的數據完整性是不可靠的, 比如對象和數組可能是null, 但是協議定義的卻是必要的, 不能是null, 這樣給前端運行時帶來風險, 所有對這些空字段可以做空默認值處理, 這個操作可以在前端獲取到數據的時進行校驗并賦予默認值, 這樣業務組件拿到的數據不會存在空類型操作錯誤。
四、總結與展望
基于協議為中心的前后端聯調模式可以為軟件開發帶來益處, 特別是對于Typescript項目, 摒棄掉了低效的重復的工作, 讓工作更集中在具體的業務實現方案上。
本次研究只是實現了基本的RESTFul的常規接口,模板也相對復雜度不高, 并不能完全處理通用Swagger協議,比如參數在路徑中, 不同http狀態碼的處理。
對于其他平臺還需研究, 比如小程序, Android(Java), IOS(Object-C)。
------ END ------
作者簡介
楊同學:?前端工程師,目前在云技術創新中心負責DMP產品的研發工作。
也許您還想看
云客后臺優化的“前世今生”(一)
云客后臺優化的“前世今生”(二)
在明源云客,一個全新的服務會經歷什么?
“弱中心”化的分布式配置管理技術可行性探索
基于 Go 的微服務運行情況監控實踐
總結
以上是生活随笔為你收集整理的Typescript前端接口联调自动化的探究与实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构与算法专题——第十二题 Trie
- 下一篇: 程序员如何跨越35岁危机?这篇给点干货建