隨著前后端分離,開發(fā)的門檻降低了,,我們不再要求團(tuán)隊(duì)中的每個(gè)開發(fā)都是全棧工程師,,這樣更容易找到項(xiàng)目的合適人選。團(tuán)隊(duì)也劃分成了前端和后端兩個(gè)團(tuán)隊(duì),。前端負(fù)責(zé)消費(fèi) API 并展示頁(yè)面,,后端負(fù)責(zé)提供 API。這兩個(gè)團(tuán)隊(duì)可以并行開發(fā)互不影響,,大大提升了效率,。雖然前后端分離解決了很多問題,但同時(shí)也帶來(lái)了新的困擾,。 前后端分離帶來(lái)的困擾溝通成本前后端成為兩個(gè)獨(dú)立團(tuán)隊(duì)之后,,協(xié)作的問題便隨之而來(lái)。通過什么來(lái)協(xié)作呢,?契約,。簡(jiǎn)單來(lái)說,就是預(yù)先定義好精準(zhǔn)的接口,,比如接口的 URL,,包含哪些參數(shù)、返回值,,每個(gè)值的類型,,是否為空等等。定義好之后,,前后端就按照契約進(jìn)行開發(fā),。但是在實(shí)際場(chǎng)景中,卻經(jīng)常出現(xiàn)問題,。 舉個(gè)真實(shí)的例子,。有一次,后端在重構(gòu)時(shí)修改了一個(gè)字段名,同時(shí)也修改了契約測(cè)試,,但是卻忘了告訴前端,。由于這個(gè)頁(yè)面的使用頻率不高,前端也工作在別的地方,,因此那個(gè)頁(yè)面掛了許久都沒有人發(fā)現(xiàn),。這些隱藏 Bug 會(huì)給我們的應(yīng)用帶來(lái)隱患,同時(shí)也會(huì)增加開發(fā)的負(fù)擔(dān),。 在實(shí)際開發(fā)過程中,,保證人人都遵守契約是一個(gè)很困難的事情,因?yàn)槿硕伎赡軙?huì)犯錯(cuò),。 大量的模板代碼即便團(tuán)隊(duì)中所有人都能嚴(yán)格遵循契約,,但集成 API 仍舊是個(gè)苦力活。我需要定義請(qǐng)求的 URL,、Method,、參數(shù)、參數(shù)類型以及返回值類型等等,。于是項(xiàng)目中就充斥著下面這樣的模板代碼:
在多人協(xié)作時(shí),,為了減少?zèng)_突,我們通常會(huì)按照業(yè)務(wù)場(chǎng)景,,將請(qǐng)求相關(guān)的代碼存儲(chǔ)到不同文件,。比如 在上面的代碼中,,我們定義了請(qǐng)求響應(yīng)數(shù)據(jù)的類型:
連接前后端為了解決上面的問題,我們實(shí)現(xiàn)了一個(gè)自動(dòng)化工具,將割裂的前端和后端重新連接起來(lái),。簡(jiǎn)單來(lái)說,,就是通過 Swagger JSON 自動(dòng)生成調(diào)用 API 所需的代碼以及類型定義。 OpenAPI 規(guī)范(以前稱為 Swagger 規(guī)范)為 RESTful API 定義了一個(gè)與語(yǔ)言無(wú)關(guān)的標(biāo)準(zhǔn)接口,,允許人和計(jì)算機(jī)發(fā)現(xiàn)和理解服務(wù)的功能,,而無(wú)需訪問源代碼、文檔或開發(fā)者工具,。Swagger 是一套圍繞 OpenAPI 規(guī)范構(gòu)建的開源工具,,可以幫助我們生成、描述,、調(diào)用和可視化 RESTful 風(fēng)格的服務(wù),。 有了自動(dòng)化工具之后,只需要在終端中執(zhí)行一行命令,,就能立刻生成項(xiàng)目中所有 API 相關(guān)的代碼以及類型定義,。這樣就不用再寫模板代碼了,節(jié)省了很多時(shí)間,。同時(shí),,由于所有代碼都是通過 Swagger JSON 生成的,當(dāng)接口發(fā)生變動(dòng)時(shí),,我們不用再去查看文檔或者詢問后端修改了什么,,只需要通過命令就能知道哪些接口發(fā)生了變化并自動(dòng)更新對(duì)應(yīng)的前端代碼。因?yàn)樗写a都是自動(dòng)生成的,,重復(fù)定義的問題也就不存在了,。對(duì)于簡(jiǎn)單業(yè)務(wù)場(chǎng)景來(lái)說,集成 API 就是一行代碼的事:
落地和優(yōu)化當(dāng)我實(shí)現(xiàn)完這個(gè)工具的第一個(gè)可用版本,,準(zhǔn)備在項(xiàng)目中推行時(shí),卻發(fā)現(xiàn)還有一些問題亟待解決: Q: 如何保證生成代碼的一致性,? A: 每次運(yùn)行命令都會(huì)從遠(yuǎn)程服務(wù)器上去獲取 Swagger JSON,,以保證數(shù)據(jù)來(lái)源的一致性。生成新的代碼之后覆蓋之前的文件即可,。這樣就能保證每個(gè)人生成的代碼與當(dāng)前服務(wù)器上的 API 是一一對(duì)應(yīng)的,。不過需要注意的是,生成的文件不能手動(dòng)修改,,否則修改最終會(huì)被覆蓋,。 Q: 如何快速得知 API 的變化? A: 跟 Q: 如何進(jìn)行多人協(xié)作,? A: 如果后端修改了一個(gè)字段名,可能會(huì)導(dǎo)致前端所有用到這個(gè)字段的地方都發(fā)生編譯錯(cuò)誤,。這時(shí)如果大家都去修改編譯問題,,不僅可能產(chǎn)生沖突,還會(huì)造成時(shí)間的浪費(fèi),。雖然這個(gè)問題在沒有自動(dòng)化工具之前一樣存在,,但仍然需要解決。好在這個(gè)問題發(fā)生的頻率不高,,我們可以和項(xiàng)目成員約定:如果有人正好在做這個(gè)功能,,那么就由他來(lái)修改,否則就由指定的人去協(xié)調(diào)安排,。通過自動(dòng)化工具,,可以更快地完成修改,從而減少阻塞別人工作的時(shí)間,。 Q: 當(dāng)后端進(jìn)度落后于前端時(shí),,如何保證先有 Swagger 定義? A: 由于前后端是兩個(gè)獨(dú)立的團(tuán)隊(duì),,所以進(jìn)度也常常不同,。后端可能無(wú)法先于前端實(shí)現(xiàn)好 API,甚至無(wú)法和前端同時(shí)開始去做一個(gè)功能,。而這套方案依賴于 Swagger 定義,,必須先有 Swagger 定義才能生成代碼。如果前端要先于后端完成某個(gè)功能,,必須先和后端商定好 API Schema 再進(jìn)行開發(fā),。定義好 API Schema 之后,隨之更新 Swagger 定義即可(后端無(wú)需實(shí)現(xiàn)具體功能),。 最后自動(dòng)化工具為前后端搭建了一座橋梁,,當(dāng)后端發(fā)生變動(dòng)時(shí),,前端也能及時(shí)得知并做出相應(yīng)修改,。再也不用擔(dān)心后端悄悄改接口了!到目前為止,,自動(dòng)化工具已經(jīng)為我們項(xiàng)目生成了上萬(wàn)行代碼,。不僅提升了大家的效率,也減少了因?yàn)椴蛔裱跫s帶來(lái)的隱藏 Bug,。前端終于不用寫大量模板代碼了,,集成 API 也變成了一件很容易的事情,。 如果對(duì)代碼實(shí)現(xiàn)感興趣,可以移步這里:ts-codegen,,或者看看我之前寫的這篇文章:基于 React 和 Redux 的 API 集成解決方案,。 |
|