快速web開發中的前后端框架選型最佳實踐


這個最佳實踐是我目前人在做的一個站點,主要功能:
  1. oauth登錄
  2. 發布文章(我稱為"片段"),片段可以自定義一些和內容有關的指標,如“文中人物:12”。支持自定義排版、插圖、建立相冊。
  3. 多個片段可以組織在一起,形成"事件"。
  4. 任意事件、片段都可以互相標記因果關系。
  5. 可以follow事件或者他人。
  6. 事件和片段模糊搜索。
我對目前前端框架的觀點已在另一篇文章中講過,這里只介紹一下目前實踐的情況。
  1. 使用requirejs做模塊化,上線時用r.js打包。
  2. 使用avalon做數據與視圖渲染框架。
  3. 用page.js來管理路由。
  4. 用harp來做靜態資源服務器。harp支持less、coffeescript等自動編譯,當前端有css或js請求而相應的文件不存在時,它就會自動查找同名的less或coffeescript等文件並編譯輸出。
 

后端選型經歷了兩周左右,目標無非兩個:開發便捷,適用於生產環境。

我對開發便捷的要求是
  1. 可簡可繁的路由配置,且非常容易生成REST接口。可棄用框架自帶的視圖層。
  2. 框架有一個良好的數據庫層,可以是ORM也可以是AR。這個數據庫層同時要支持開發者手動優化查詢。
  3. 框架依賴少,容易安裝和部署,社區支持強大。
對適用於生產環境的要求是:
  1. 框架本身輕巧,速度快。
  2. 支持大並發,有成熟集群部署方案。
  3. 能切換各種類型的數據庫,有memcached等緩存中間件的接口。
 
在這期間,我試用了Django、drupal、 discuz、codeigniter、 expressjs、sails,以下記錄選擇過程中對前后端的考慮,希望對有類似需求的朋友有幫助。我的定論留在文章最后。
 
Django
比較慚愧,出於個人對python不如php和nodejs熟,放棄了Django。Django自帶功能非常強大的ORM,有REST中間件。也有成熟的部署方案。並且有非常好的學習指南(搜"Django book"),推薦各位一定要自己用用。
 
drupal
要完整地描述和概括drupal有一點難。它既不是某一種具體業務邏輯的框架(把它說成CMS太狹隘),也不是純粹的只有功能層面(如ORM、視圖渲染)的框架。只能這樣說:
首先,它包含了強大的功能層,如數據庫層、視圖層。其次,它通過“hook”機制以及一整套完善的附屬功能,讓開發者能非常自由地打造自己的業務邏輯。或者說使得它可以幾乎可以包容任何業務邏輯。類似於AOP,類似於裝飾類。
 
這里為不懂的讀者再介紹一下它的核心“hook”。實現一個hook有兩步:一、在業務流程中的某些點聲明可以被hook。二、聲明一個操作,和它要hook到哪個流程中的點。比如:一個用戶注冊模塊聲明,在獲取用戶的注冊數據后,寫到數據庫之前,這一點可以被hook。一個加密模塊聲明,要對注冊數據中的密碼進行加密,並聲明這個操作hook到剛才提到的用戶模塊聲明的點上。這樣在寫到數據庫前,密碼就被加密了。
 
hook機制早已有之,drupal的精髓在於將其發展並運用到幫助開發者實現業務邏輯上。因為幾乎任何人類的業務邏輯都是流程化的,並且很可能變化。hook滿足了在不直接改變原有邏輯的情況下進行擴展和修改的需求。也是這種機制激活了drupal的開發社區,讓它的每一個模塊都能很好地與其他模塊協作。
 
一開始我其實是選用了drupal做后端的。第一,它的后端功能十分完善,從用戶注冊到內容管理應有盡有。實在沒有還可以去它強大的社區找支援。第二,drupal在部署、性能優化方面已經非常成熟。但最后仍然棄用了,這里先說說用的過程。
 
首先裝上Service模塊自動實現drupal的REST api,這時候節點、用戶什么的增刪改查接口就已經都有了,只需要按照Services的說明去打開這些接口就行。如果需要跨域調用,還要裝上CORS模塊來允許跨域請求,相關知識請自行google CORS。如果定制更多的查詢接口,可以裝上Services Views模塊,它能直接將views生成的列表變成數據輸出,不過這個模塊和views本身一樣有個讓人很不爽的點:對於多值的字段,不能按數組輸出,只能輸出成一行字符串,以",“或者其他指定符號分割。
至此,后端已基本可用。然而隨着繼續開發,有了更多的需求,比如說投票。drupal有很多投票模塊,但幾乎都是直接嵌入到頁面中的,對api支持不好。於是想自己寫一個。這樣的功能多了以后發現,去找有沒有類似模塊,並調研是否符合我需求和踩坑的時間都已經超過了自己開發的時間。如此一來都已經脫離我”快速開發“的本意了。況且如果都要自己寫,為什么不選個輕量級的框架呢?比如codeigniter。於是開始便繼續寫,邊尋覓其他框架。drupal整體而言其實應該是非常適合團隊開發的,因為它迫使大家都遵循同樣的機制,這樣就解決了團隊開發容易質量不可控這樣一個最大的風險。對個人開發者來說,總是先搭個架子,或者先看看別人的架子是怎么搭的,再開始寫代碼,實在有點累。
 
discuz
看完drupal再看discuz、phpwind什么的,完全不能接受,架構太亂,控制器、模型、視圖耦合嚴重。沒有對REST api好的支持。略過。
 
codeigniter
codeigniter確實是非常輕,一個自動映射到控制器的路由系統,一個以AR方式實現的數據庫層,一個可用可棄的視圖層。就這么簡單。 codeigniter同樣也有良好的社區支持,然而更重要的是, 正是因為它非常簡單,讓它可以幾乎無痛的與任何第三方類庫集成。不過自己的業務邏輯,就得一點一點自己搭建了。如果是這樣的話,那還是用nodejs的框架更好。
 
expressjs
expressjs是我所知的目前最成熟的nodejs框架了(如有其它更好的,只能說我孤陋寡聞了)。選nodejs框架最大優點: 第一,沒有切換語言編程的痛苦。 第二,nodejs在處理並發、大規模部署都已經有成功經驗。 第三, 能夠良好地支持各種數據庫。如果不是發現了sails的話,我應該就選expressjs了。
 
sails
對我個人來說,對小框架其實是有戒心的。特別是對於要上線的程序,萬一碰到問題問作者,作者撒手不管,也沒有大規模部署的例子等等情況,上線后可能就會面臨推倒重來的結局。所以不能只看開發體驗,框架的出身也是很重要的。首先值得說明的是,sails是基於expressjs的。 稍微讓人放心了點。其次,sails雖然自稱實時框架,強調自己對於web socket的封裝。但我目前只需要用到它的ORM和自動生成REST api。畢竟這兩個基礎的東西看看源碼是可以自己掌握的。下面來介紹以下實踐過程:
 
首先是路由系統。分為兩個部分,一個是sails對每一個model自動生成的REST api。sails支持標准的REST請求,同時也能讓開發者通過配置文件將接口修改為常用的REST變種接口。另一部分是用戶自己定義的接口,和codeigniter一樣,sails也是自動將接口映射到相應controller的方法上,非常簡單。它同時還提供了稱之為polices的機制來保護接口,即在調用指定接口之前先用定義好的police檢測一遍,不通過則直接拒絕請求。這樣能讓controller更專注於具體業務邏輯。
 
然后講講數據層。sails的數據庫適配器非常多,幾乎所有的主流的數據庫都能支持。它也是通過寫配置文件,來實現對字段的定義。一個叫做'Event'的模型例子:
module.exports = {
  attributes: {
        uid: {
            type : 'string',
            defaultsTo : ''
        },
        title: {
            type:'string',
            required : true,
        },
        content : 'string',
        vote : {
            type : 'integer',
            defaultsTo : 0
        }
    },
    afterCreate:function( event,next ){
        Heat.create({
            entity_id : event.id,
            type : 'event'
        }).done(function(){
            next()
        })
    }
};
在這段代碼里可以看出,sails的定義實現了主流數據庫中對字段的檢測、設置默認值等功能。值得一提的是例子最后的'afterCreate'函數,這是sails提供的類似於drupal hook的東西,它自己稱為"生命周期回調"。它可以讓開發者在模型的增刪改查前后自動執行相應的管理操作。在我們的例子里就是在一條屬於Event模型的記錄創建之后,再創建一條相關的Heat模型的數據。
要注意的是sails ORM中是沒有自動支持模型建的關聯的。以我個人的觀點來說,正好也不需要,因為模型間的關聯常常是造成數據庫查詢負載的罪魁禍首,我常常通過儲存冗余數據等方法來盡量減少關聯查詢。所以不支持模型關聯,正好讓我每一個需要關聯的地方都手寫,保障性能。
數據庫我用了mongodb,我的需求里面有些非結構化的數據可以無需任何轉換地存到數據庫了。sails同時還支持對不同的model使用不同的數據庫,這樣未來要對數據庫調優的話空間就很大了。
 
最后看看下對CORS的支持,直接在整站的配置文件中打開crsf選項即可。對於跨站請求,先請求crsf token,之后的請求帶上這個頭就可以跨站了。
 
結論自然是選擇了sails。目前sails整體項目官方維護得非常積極,功能完備。實在有問題了看看源碼也能夠明白。相對於我的需求來說已經非常好了。
 
最后整體總結一下:
1.整個開發中前后端完全分離。后端只提供數據接口,並且支持跨域請求,也便於之后進行其他端的開發。
2.前端用avalon、requirejs、page.js三件套開發體驗非常好。用harp來支持less和coffeescript等,自動編譯,無需任何中間操作。
3.后端用sails來處理業務邏輯和提供REST api。各種功能齊全,開發順暢。
 
文中內容若有偏頗,望不吝賜教。預祝屏幕前的你新年快樂。
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM