相信先後端分離這個詞,早已流傳甚廣,你們一些本身的理解,但可能有些人的觀點有稍許誤差:咱們要搞 SPA,全AJAX,那纔是先後端分離了。css
什麼是先後端分離
咱們來聊聊什麼是先後端分離。html
先來看一張WEB系統先後端架構模型圖。前端
WEB系統先後端架構模型
從圖中能夠清晰的看到,先後端的界限是按照瀏覽器和服務器的劃分。那麼咱們常常會發現一些問題:git
- 模板層歸屬前端仍是後端?
- 模板強依賴於後端渲染,前端開發須要等待後端開發嗎?
一般狀況,模板層歸屬於前端,由於讓後端人員來接觸他們不擅長的樣式和 js 交互是很蛋疼的事情。github
那麼,做爲前端開發的咱們在實際的開發場景中又會遇到如下問題:web
- 環境:進行本地開發,須要起後端環境,如 Tomcat、PHP,影響開發效率
- 流程:前端開發先開發 html,再將 html 改寫成指定的模板語法(俗稱套模板),影響開發效率
- 接口:
- 接口定義通常使用 word 文檔,前端開發時很差理解接口字段,影響開發效率
- 接口變動須要從新編寫文檔,並從新發送,影響開發效率
- 文檔散落,影響接口維護
- 聯調:
- 聯調過程變得很複雜,尤爲是沒有作熱部署的Java工程,改視圖還須要重啓Tomcat,影響前端聯調效率
- 效益:
- 前端開發更關注用戶體驗,然後端只但願關注數據可靠,爲實現如響應式、ssr之類的一些交互,前端須要掌控必定的請求響應能力
- 若是先後端對接的方式轉變成爲純粹的 JSON 交換,對於提高開發效率、更清晰的職責與接口複用都是有好處的
出現影響開發效率的事情,就說明現有的模式存在問題,顯然問題的解題思路須要咱們從新思考「先後端」的定義。此時,先後端分離的概念便應運而生,目的是將先後端開發人員的合做方式調節到你們都儘量溫馨的姿式。後端
有哪些實現方案
SPA
SPA
全稱 Single Page Application,使用前端路由的方式代替後端的 controller,並使用前端模板代替後端的模板引擎渲染,使用 restful api 實現與後端的數據交互。
在這個方案中,先後端的交互被轉換成了純粹的 http 方式的 JSON 串交互。設計模式
SPA 的優點:
- 環境:前端開發者不須要本地起後端環境
- 流程:獨立的前端開發方式,因爲後端返回純 JSON ,前端想要模擬請求響應的話,只需啓動一個純靜態的服務器,響應 JSON 格式的 html 便可
- 聯調:清晰的對接方式,JSON 對於先後端來講都是比較純粹的
- 效益:對於用戶來講,用戶體驗的提高
SPA 的劣勢
- SEO 弱
- 首屏加載慢,等全部 js 加載完才能出首屏
- 前端須要處理一些本不須要在這一層處理的事情,如權限控制交給前端控制
綜上,SPA 是一個能夠解決先後端分離的有效方案,對於無 SEO 要求的項目大能夠嘗試。api
開發階段的分離 -- Mock && Proxy
顧名思義,開發階段的先後端分離,須要依賴工具實現,一般把這個工具叫作 Mock Server(如筆者所開發的一款 Mock Server -- Foxman)。瀏覽器
Mock Server 提供功能
基礎功能
- 攔截同步請求,取 JSON 格式的 Mock 數據,結合本地 Template,經過模板渲染引擎渲染,得出響應的頁面
- 攔截異步請求,取 JSON 格式的 Mock 數據響應
這裏咱們須要抽象以上操做爲兩個函數,利於理解:
- SyncView = TemplateEngine(Template, MockData)
- AsyncView = MockDataTransform(MockData)
優化功能
- Living Reload -- 監聽本地文件,發生修改則通知(通常使用 websocket)瀏覽器更新資源
- 修改響應頭 -- Mock 階段,能夠作到 js 修改響應狀況
- 代理 -- 前面提到了兩個函數,代理的指責是將本來取自本地的 MockData,改爲了從服務端以 http 的方式取得的數據
開發流程
咱們將一個項目開發劃分爲三個階段:接口定義,開發,聯調。正好能夠和咱們 「Mock」、 「Proxy」 兩個工具契合。
讓咱們經過實際的場景來表述這種先後端的合做方式。
接口定義
咱們接到一個需求,實現某個功能。在咱們理清楚具體的功能以後,應該與後端定義接口及返回,包括:
- 有哪些頁面,頁面的請求路徑,模板位置,以及後端返回給咱們的 Model 內容
- 有哪些 Ajax 接口,Ajax接口 的請求路徑,以及後端返回的 JSON 內容
在制定完接口後,咱們須要按照 Mock Server 的要求,建立 Mock 文件,並往裏面填入與後端約定好的 JSON 數據,並與後端確認。
顯然咱們的開發中,接口定義變成了一件很具體的事情,而開發階段可使用這份 Mock 數據,並作到 Mock 數據即接口文檔
開發階段
在咱們完成接口定義後,咱們指望的是無打擾、自治的一個開發體驗。
正如上圖所示,開發階段前端開發能夠徹底與後端開發人員隔絕,也不須要本地啓動後端環境,咱們要作的,只是按照先前指定的接口及本地的 Mock 文件進行需求的開發。
而在開發過程當中,遵循 html -> css -> js 的開發順序,Foxman 擁有一個很人性化的 live reload(更改css 之會 reload css),總之接口定義合理的話,這一步會很順暢。
聯調階段
在咱們開發完頁面後,咱們指望的是與後端進行聯合調試,已驗證功能開發是否存在缺陷,即聯調階段。
在這步驟中,咱們只須要更換 SyncView = TemplateEngine(Template, MockData)
的 MockData,將本來響應自 Mock 文件的請求,轉發到真實的目標服務器(在聯調階段會是 開發主機 或者 測試機)。
此處代理和轉發,筆者已抽象成了的另一個庫 koa-api-forward,歡迎交流和使用。
Mock && Proxy 優點
- 環境:
- 流程:
- 獨立的前端開發方式,Mock 與 Proxy 結合,流程清晰
- 前端能夠在本地調試 view 層,大幅度提高前端的聯調效率
- 聯調:
- 清晰的對接方式,JSON 實現先後端來講都是比較純粹的
- 效益:
Mock && Proxy 劣勢
- 未真正掌握線上的接口響應,實現一些前端交互需求(響應式)時仍依賴後端,或沒法進行(如 ssr)
Node.js 中間層
https://user-gold-cdn.xitu.io/2017/10/5/956f5231f02144f4b6ef87a50abf2ce0
這個模式天然時結合了前面的 Proxy。你們都知道 Node.js Server 裏面強調一個 中間件的 概念,對應到設計模式的職責鏈模式。即只處理本身能處理的狀況,不然,繼續日後傳遞,直到被處理。
這個方案中,Proxy 做爲了中間件體系中的最後一層,用以轉發請求,而在這以前依次是中間件的錯誤處理、靜態資源的響應、路由攔截(routers) 等等。
Node.js 擁有必定的接口控制能力,如處理 PC/Mobile 的響應式渲染,或是 Server-Side-Render 等等。
Node.js 中間層優點
- 環境:
- 聯調:
- 清晰的對接方式,JSON 實現先後端來講都是比較純粹的
- 效益:
- 可漸進式,前期能夠將請求所有轉發後端服務器,然後能夠逐步將 Node.js 層做爲用戶的直接數據交換層
- 職責分明,後端服務化,Node.js 層處理接口用戶相關的頁面響應 及 數據交換
- 可組合性,後端服務化,Node.js 負責組合拼裝,實現接口可複用率
Node.js 中間層劣勢
- 開發階段仍須要 Mock 支持,若是將 Mock 方式整合進 Node.js 中間層,則形成 Node.js 中間層職責不純粹
- 對現有系統的漸進式改造是個較爲漫長的過程
總結
仍是那句話,全部的先後端分離方案,都是爲了先後端開發人員的合做方式調節到你們都儘量溫馨的姿式。
那麼一個不錯的實踐是,咱們能夠將 (Mock && Proxy) 與 Node.js 中間層 兩個方案結合:
- Mock && Proxy 只依靠抽象出來的工具,在前端開發階段,繼續使用,避免形成 Node.js 中間層職責不純粹
- Node.js 中間層的存在能夠解決(Mock && Proxy)方案的劣勢
未完待續。。。
參考資料
by 君羽