做者:戴嘉華前端
轉載請註明出處,保留原文連接和做者信息程序員
開發一個Web應用的時候咱們通常都會簡單地分爲前端工程師和後端工程師(注:在一些比較複雜的系統中,前端能夠細分爲外觀和邏輯,後端能夠分爲CGI和Server)。前端工程師負責瀏覽器端用戶交互界面和邏輯等,後端負責數據的處理和存儲等。先後端的關係能夠淺顯地歸納爲:後端提供數據,前端負責顯示數據。ajax
在這種先後端的分工下,會常常有一些疑惑:既然前端數據是由後端提供,那麼後端數據接口尚未完成,前端是否就沒法進行編碼?怎麼樣才能作到先後端獨立開發?後端
考慮這麼一個場景:Alex和Bob是一對好基友,他們有個能夠顛覆世界的idea,準備把它實現出來,可是他們不須要程序員,由於他們就是程序員。說幹就幹,兩個就幹上了。Alex寫前端,Bob寫後端。跨域
Alex和Bob都通過良好的訓練,循序漸進地把產品的主要功能設計,交互原型,視覺設計作好了,而後他們根據產品功能和交互制定了一堆叼炸天的先後端交互的API,這套API就相似於一套先後端開發的「協議」,Alex和Bob開發的時候都須要遵照。例如其中一個發表評論的功能:瀏覽器
// API: Create New Comment v2 // Ajax, JSON, RESTful url: /comments type: POST request: {content: "comment content.", userId: 123456} response: - status: 200 data: {result: "SUCCESS", msg: "The comment has been created."} - status: 404 data: {result: "failed", msg: "User is not found."}
Alex的前端須要向/comments
這個url以POST
的方式發送相似於{content: "comment content.", userId: 123456}
這樣的JSON請求數據;Bob的服務端識別後之後,操做成功則返回200狀態和上面的JSON的數據,不一樣的操做狀態有不一樣的響應數據(爲了簡單起見只列出了兩種,200和404)。服務器
API制定完之後,Alex和Bob就開始編碼了。Alex把評論都外觀和交互寫完了,可是寫到發表評論功能就納悶了:Alex如今須要發Ajax過去,可是隻能把Ajax代碼寫好,由於是本地服務器,卻沒法獲取到數據:前端工程師
// jQuery Ajax $.ajax({ // 這個ajax直接報錯,由於這個是Alex的前端服務器,請求沒法獲取數據; url: "/comments", type: "POST", data: {content: content, userId: userId}, success: funtion(data) { // 這裏不會被執行 } })
相比起來Bob就沒有這個煩惱,由於後端是基於測試驅動開發,且後端能夠輕易地模擬前端發送請求,能夠對前端沒有依賴地進行開發和測試。app
Alex把這種狀況和Bob說了,Bob就說,要不咱們把代碼弄到你本地先後端鏈接一下,這不就能夠測試了嗎。Alex以爲Bob簡直是天才。前後端分離
他們把先後端代碼代碼都部署到Alex的本地服務器之後,通過一系列的測試,調試,終於把這個API鏈接成功了。可是他們發現這個方法簡直不科學:難道每寫一個API都要把先後端連接測試一遍嗎?並且,Alex的若是須要測試某個API,而Bob的這個API還沒寫好,Alex這個功能模塊的進度就「阻塞」了。
後面還有168個API須要寫,不能這麼作。Alex和Bob就開始思考這個問題的解決方案。
在這個場景下,先後端是有比較強的數據依賴的關係,後端依賴前端的請求,前端依賴後端的響應。然後端能夠輕鬆模擬前端請求(基本上能寫後端的語言均可以直接發送HTTP請求),前端沒有一個比較明顯的方案來能夠作到模擬響應,因此這裏的須要解決的點就是:如何給前端模擬的響應數據。
先來一句很是形而上的話:若是兩個對象具備強耦合的關係,咱們通常只要引入第三個對象就能夠打破這種強耦合的關係。
+---------+ +---------+ | | | | | Object1 | <--------> | Object2 | | | | | +---------+ +---------+ Before +---------+ +---------+ | | | | | Object1 | <-- ✕ ---> | Object2 | | | | | +---+-----+ +-----+---+ | | | | | | | | | | | +---------+ | | | | | +-----> | Object3 | <------+ | | +---------+ After
在咱們上述開發的過程當中,先後端的耦合性太強了,咱們須要藉助額外的東西來打破它們的耦合性。因此,在先後端接口定下來之後,咱們根據接口構建另一個Server,這個Server會一一響應前端的請求,而且根據接口返回數據。固然這些數據都是假數據。咱們把這個Server叫作Mock Server,而Bob真正在開發的Server叫作Real Server。
+-------------------+ +-------------------+ | | +-------- ✕ ------> | | | Browser | | Real Server | | | <---+ | | +--------------+----+ | +-------------------+ | | | | | | | | Request Response | | | | | | | +----+--------------+ +---> | | | Mock Server | | | +-------------------+
Mock Server是根據API實現的,可是是沒有數據邏輯的,只是很是簡單地返回數據。例如上面Alex和Bob的發表評論的接口在Mock Server上是這樣的:
// Mock Server // Create New Comment API route.post("/comments", function(req, res) { res.send(200, {result: "Success"}); })
Alex在開發的時候向Mock Server發出請求,而不是向Bob的服務器發出請求:
// Sending Request to Mock Server // jQuery Ajax $.ajax({ url: config.HOST + "/comments", type: "POST", data: {content: content, userId: userId}, success: funtion(data) { // OK } })
注意上面的config.HOST
,咱們把服務器配置放在一個全局共用的模塊當中:
// Front-end Configuration Module var config = modules.exports; config.HOST = "http://192.169.10.20" // Mock Server IP
那麼上面咱們實際上是向IP爲http://192.169.10.20
的Mock Server發出請求http://192.169.10.20/comments
發出POST的請求。
當Alex和Bob都代碼寫好了之後,須要鏈接調試了,Alex只要簡單地改一下配置文件便可把全部的請求都轉向Bob所開發的Real Server:
// Front-end Configuration Module var config = module.exports; // config.HOST = "http://192.169.10.20" // Mock Server IP config.HOST = "http://changing-world-app.com" // Real Server Domain
而後Alex和Bob就能夠愉快地分離獨立開發,而最後只須要聯合調試就能夠了。
總結一下基本上先後端分離開發包括下面幾個步驟:
固然要注意,若是接口修改了,Mock Server要同步修改。
Mock Server具體應該如何構建?應該存放在哪裏?應該怎麼維護?
先後端是不一樣的兩個工程,它們各自佔用一個倉庫。Mock Server應該和它們分離出來,獨立進行開發和維護,也就是說會有三個倉庫,Mock Server是一個單獨的工程。
Mock Server能夠部署在本地,也能夠部署到遠程服務器,二者之間各有優劣。
作法:把Mock Server工程部署到一個遠程的always on的遠程服務器上,前端開發的時候向該服務器發請求。
優勢:
缺點:
(在寫這篇博客的時候,逛Hacker News,恰好看到有人作了一個開發輔助工具(http://reqr.es/),能夠用於開發時響應前端請求,其實也就是這裏所說的遠程Mock Server。真是不能再巧更多。)
作法:前端把Mock Server克隆到本地,開發的時候,開啓前端工程服務器和Mock Server,全部的請求都發向本地服務器,獲取到Mock數據。
優勢:
缺點:
Mock Server工程通常能夠由後端開發人員來維護。由於在開發的過程當中,後端由於各類緣由可能須要修改API,後端人員是最熟悉請求的響應數據和格式的人,能夠同步維護Mock Server和Real Server,更好保證數據的一致。Mock Server維護起來並不複雜,對於比較大多工程來講,這樣的前期準備和過程的維護是很是值得的。
因此要點就是:根據API構建能夠模擬服務器響應的Mock Server,用於前端請求模擬數據進行測試。
再重複總結一下先後端分離開發包括下面幾個步驟:
當開發只有我一我的的時候,我更喜歡後端獨立開發,開發前端的時候開個Real Server來作響應。又爽又快。其實若是團隊的人是full-stack的話,徹底能夠按照功能模塊來劃分任務,而不是分爲前端工程師和後端工程師。
但通常來講仍是會選擇先後端職能劃分,對於這種狀況下的多人開發的工程來講,先後端分離開發的方式確實須要考慮和構建的,能夠更好幫助咱們構建一個高效,規範化,流程化的開發流程。
仍是那句話,沒有銀彈,全部的東西都須要根據實際狀況來構建獨特的流程。
無
(全文完)