每個應用都由兩樣東西構成:該應用獨有的功能和所有應用共有的功能,比方說使用者註冊、登入、忘記密碼等。而從使用者的角度出發,那些獨有的功能歸結起來就是使用者介面以及系統的行為模式。而在視覺表象之後的功能,使用者並不關心,他們只期望系統能按預期執行就可以了。
前端和後端有各自的側重點,因此往往也需要不同的技能,由不同的開發人員來負責完成。無後端(nobackend)的開發原則能夠進一步解偶這些不同的側重點,這樣兩邊的開發人員可以更加專注於各自真正熱衷的工作。
一個簡單的例子
後端經常需要提供API給前端,以下是一個簡單的例子,使用API進行使用者登入。
1 2 |
POST /session { "email":"joe@example.com", "password": "secret" } |
前端的開發人員需要負責傳送上述請求並對結果進行響應,還要考慮到一些極端的情況,如失去連線或不可預知的伺服器錯誤等。與此相反的是,無後端的設計原則則建議由前端開發人員來定義API,用前端的程式碼來描述後端的功能,舉例如下:
1 2 3 |
signIn( 'joe@example.com', 'secret' ) .then( showDashboard ) .fail( showError ) |
我們稱此為夢幻程式碼(Dreamcode),因為這些程式碼經常是在真正的程式碼可執行以前就已經寫好了。初一看,這樣並沒有多大意義,只不過是改成了傳送AJAX請求並呼叫相應的回撥函式而已,但是以這樣的方式定義的API在許多方面都會更加強大:
1. 靈活
使用者如果想要登入,那麼他們也就只關心登入這個行為本身,而絕不會去關心:
- 請求是否是送到應用的伺服器還是一箇中央的驗證伺服器
- 是一個HTTP的POST請求還是PUT請求。
- 是否是通過websocket傳送的
- 驗證使用的cookies還是使用session ID或者是自定義的header
- 應用是否會在前一個請求時後再次傳送請求
signIn這個方法的實現可以進行調整以反映後端的變化,但是就這個API本身,前端開發人員並不需要去修改了。
2. 簡潔
從前端開發人員的角度來看,實現signIn方法要簡單的多,程式碼量也可以少很多;而從後端開發人員的角度來看,儘管剛開始要投入更多的精力,但是和RESTful API相比,前面的API要更容易定義,文件化和測試。
3. 前端驅動
前端開發人員可以引領構建應用的整個設計流程。以Dreadcode的方式來描述後端的功能,可以讓開發人員更加專注於使用者體驗,從而避免了由於討論具體的實現細節而有所分心,也不會由於要等待後端API的實現而拖延專案的進度。
一個更加複雜的例子
當你研究一個更復雜的例子以後,前優勢會顯得更加明顯。假設你想要傳送一封郵件,要附上當前頁的PDF。
1 2 3 4 5 6 7 8 9 |
sendEmail({ subject: "Hello, World!", text: "This mail has been sent from the frontend", html: "This mail has been sent from the frontend", to: "joe@example.com", attachments: [ convert( document.body ).to("report.pdf"), ] }) |
要讓這段程式碼跑起來,並且要讓它不受垃圾郵件的影響,可能會相當困難。但是至少可以馬上寫一些quick和dirty的實現,然後再一點一點地改進,而在這個過程中無需改變API。這裡的關鍵點在於,前端開發人員可以把這看成是一個已有的功能,從而可以專注於使用者體驗,而不需要去關心後臺開發人員到目前為止究竟有多麼複雜地實現了這個功能。
現有的一些nobackend的解決方案
一個nobackend的解決方案應該提供一個前端的API來處理一些通用的後端任務,至少應該包括使用者驗證、資料持久化和同步等。以下是一些可以關注的方案:
也可以參考下:unhosted。以上這個列表中,絕大多數都是託管服務,對於想要用自己的伺服器來託管的同學,可以選擇開源的deployd。