實踐中的先後端分離

相信先後端分離這個詞,早已流傳甚廣,你們一些本身的理解,但可能有些人的觀點有稍許誤差:咱們要搞 SPA,全AJAX,那纔是先後端分離了。css

什麼是先後端分離

咱們來聊聊什麼是先後端分離。html

先來看一張WEB系統先後端架構模型圖。前端

WEB系統先後端架構模型
WEB系統先後端架構模型

從圖中能夠清晰的看到,先後端的界限是按照瀏覽器和服務器的劃分。那麼咱們常常會發現一些問題:git

  1. 模板層歸屬前端仍是後端?
  2. 模板強依賴於後端渲染,前端開發須要等待後端開發嗎?

一般狀況,模板層歸屬於前端,由於讓後端人員來接觸他們不擅長的樣式和 js 交互是很蛋疼的事情。github

那麼,做爲前端開發的咱們在實際的開發場景中又會遇到如下問題:web

  1. 環境:進行本地開發,須要起後端環境,如 Tomcat、PHP,影響開發效率
  2. 流程:前端開發先開發 html,再將 html 改寫成指定的模板語法(俗稱套模板),影響開發效率
  3. 接口:
    • 接口定義通常使用 word 文檔,前端開發時很差理解接口字段,影響開發效率
    • 接口變動須要從新編寫文檔,並從新發送,影響開發效率
    • 文檔散落,影響接口維護
  4. 聯調:
    • 聯調過程變得很複雜,尤爲是沒有作熱部署的Java工程,改視圖還須要重啓Tomcat,影響前端聯調效率
  5. 效益:
    • 前端開發更關注用戶體驗,然後端只但願關注數據可靠,爲實現如響應式、ssr之類的一些交互,前端須要掌控必定的請求響應能力
    • 若是先後端對接的方式轉變成爲純粹的 JSON 交換,對於提高開發效率、更清晰的職責與接口複用都是有好處的

出現影響開發效率的事情,就說明現有的模式存在問題,顯然問題的解題思路須要咱們從新思考「先後端」的定義。此時,先後端分離的概念便應運而生,目的是將先後端開發人員的合做方式調節到你們都儘量溫馨的姿式。後端

有哪些實現方案

SPA

SPA
SPA

全稱 Single Page Application,使用前端路由的方式代替後端的 controller,並使用前端模板代替後端的模板引擎渲染,使用 restful api 實現與後端的數據交互。

在這個方案中,先後端的交互被轉換成了純粹的 http 方式的 JSON 串交互。設計模式

SPA 的優點:

  1. 環境:前端開發者不須要本地起後端環境
  2. 流程:獨立的前端開發方式,因爲後端返回純 JSON ,前端想要模擬請求響應的話,只需啓動一個純靜態的服務器,響應 JSON 格式的 html 便可
  3. 聯調:清晰的對接方式,JSON 對於先後端來講都是比較純粹的
  4. 效益:對於用戶來講,用戶體驗的提高

SPA 的劣勢

  1. SEO 弱
  2. 首屏加載慢,等全部 js 加載完才能出首屏
  3. 前端須要處理一些本不須要在這一層處理的事情,如權限控制交給前端控制

綜上,SPA 是一個能夠解決先後端分離的有效方案,對於無 SEO 要求的項目大能夠嘗試。api

開發階段的分離 -- Mock && Proxy

顧名思義,開發階段的先後端分離,須要依賴工具實現,一般把這個工具叫作 Mock Server(如筆者所開發的一款 Mock Server -- Foxman)。瀏覽器

Mock Server 提供功能

基礎功能

  • 攔截同步請求,取 JSON 格式的 Mock 數據,結合本地 Template,經過模板渲染引擎渲染,得出響應的頁面
  • 攔截異步請求,取 JSON 格式的 Mock 數據響應

這裏咱們須要抽象以上操做爲兩個函數,利於理解:

  1. SyncView = TemplateEngine(Template, MockData)
  2. AsyncView = MockDataTransform(MockData)

優化功能

  • Living Reload -- 監聽本地文件,發生修改則通知(通常使用 websocket)瀏覽器更新資源
  • 修改響應頭 -- Mock 階段,能夠作到 js 修改響應狀況
  • 代理 -- 前面提到了兩個函數,代理的指責是將本來取自本地的 MockData,改爲了從服務端以 http 的方式取得的數據

開發流程

咱們將一個項目開發劃分爲三個階段:接口定義,開發,聯調。正好能夠和咱們 「Mock」、 「Proxy」 兩個工具契合。
讓咱們經過實際的場景來表述這種先後端的合做方式。

接口定義

咱們接到一個需求,實現某個功能。在咱們理清楚具體的功能以後,應該與後端定義接口及返回,包括:

  1. 有哪些頁面,頁面的請求路徑,模板位置,以及後端返回給咱們的 Model 內容
  2. 有哪些 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 優點

  1. 環境:
    • 前端開發者不須要本地起後端環境
  2. 流程:
    • 獨立的前端開發方式,Mock 與 Proxy 結合,流程清晰
    • 前端能夠在本地調試 view 層,大幅度提高前端的聯調效率
  3. 聯調:
    • 清晰的對接方式,JSON 實現先後端來講都是比較純粹的
  4. 效益:
    • 方便開發的同時,保持線上系統的無侵入

Mock && Proxy 劣勢

  1. 未真正掌握線上的接口響應,實現一些前端交互需求(響應式)時仍依賴後端,或沒法進行(如 ssr)

Node.js 中間層

https://user-gold-cdn.xitu.io/2017/10/5/956f5231f02144f4b6ef87a50abf2ce0
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 中間層優點

  1. 環境:
    • 前端開發者不須要本地起後端環境
  2. 聯調:
    • 清晰的對接方式,JSON 實現先後端來講都是比較純粹的
  3. 效益:
    • 可漸進式,前期能夠將請求所有轉發後端服務器,然後能夠逐步將 Node.js 層做爲用戶的直接數據交換層
    • 職責分明,後端服務化,Node.js 層處理接口用戶相關的頁面響應 及 數據交換
    • 可組合性,後端服務化,Node.js 負責組合拼裝,實現接口可複用率

Node.js 中間層劣勢

  • 開發階段仍須要 Mock 支持,若是將 Mock 方式整合進 Node.js 中間層,則形成 Node.js 中間層職責不純粹
  • 對現有系統的漸進式改造是個較爲漫長的過程

總結

仍是那句話,全部的先後端分離方案,都是爲了先後端開發人員的合做方式調節到你們都儘量溫馨的姿式。

那麼一個不錯的實踐是,咱們能夠將 (Mock && Proxy) 與 Node.js 中間層 兩個方案結合:

  1. Mock && Proxy 只依靠抽象出來的工具,在前端開發階段,繼續使用,避免形成 Node.js 中間層職責不純粹
  2. Node.js 中間層的存在能夠解決(Mock && Proxy)方案的劣勢

未完待續。。。

參考資料

by 君羽

相關文章
相關標籤/搜索