(三)Midway-ModelProxy — 輕量級的接口配置建模框架

2018-02-24 16:04 更新

原文:http://ued.taobao.org/blog/2014/04/modelproxy/
作者:善繁

前言

使用Node做前后端分離的開發(fā)模式帶來了一些性能及開發(fā)流程上的優(yōu)勢(見《前后端分離的思考與實(shí)踐 一》), 但同時(shí)也面臨不少挑戰(zhàn)。在淘寶復(fù)雜的業(yè)務(wù)及技術(shù)架構(gòu)下,后端必須依賴Java搭建基礎(chǔ)架構(gòu),同時(shí)提供相關(guān)業(yè)務(wù)接口供前端使用。Node在整個(gè)環(huán)境中最重要的工作之一就是代理這些業(yè)務(wù)接口,以方便前端(Node端和瀏覽器端)整合數(shù)據(jù)做頁面渲染。如何做好代理工作,使得前后端開發(fā)分離之后,仍然可以在流程上無縫銜接,是我們需要考慮的問題。本文將就該問題做相關(guān)探討,并提出解決方案。

  • 第二步 在代碼中創(chuàng)建并使用model
// 引入模塊
var ModelProxy = require( 'modelproxy' ); 

// 全局初始化引入接口配置文件  (注意:初始化工作有且只有一次)
ModelProxy.init( './interface.json' );

// 創(chuàng)建model 更多創(chuàng)建模式請參后文
var searchModel = new ModelProxy( {
    searchItems: 'Search.getItems'  // 自定義方法名: 配置文件中的定義的接口ID
} );

// 使用model, 注意: 調(diào)用方法所需要的參數(shù)即為實(shí)際接口所需要的參數(shù)。
searchModel.searchItems( { q: 'iphone6' } )
    // !注意 必須調(diào)用 done 方法指定回調(diào)函數(shù),來取得上面異步調(diào)用searchItems獲得的數(shù)據(jù)!
    .done( function( data ) {
        console.log( data );
    } )
    .error( function( err ) {
        console.log( err );
    } );

ModelProxy的功能豐富性在于它支持各種形式的profile以創(chuàng)建需要業(yè)務(wù)model:

  • 使用接口ID創(chuàng)建>生成的對象會取ID最后’.’號后面的單詞作為方法名
ModelProxy.create( 'Search.getItem' );
  • 使用鍵值JSON對象>自定義方法名: 接口ID
ModelProxy.create( {
    getName: 'Session.getUserName',
    getMyCarts: 'Cart.getCarts'
} );
  • 使用數(shù)組形式>取最后 . 號后面的單詞作為方法名
    下例中生成的方法調(diào)用名依次為: Cart_getItem, getItem, suggest, getName
ModelProxy.create( [ 'Cart.getItem', 'Search.getItem', 'Search.suggest', 'Session.User.getName' ] );
  • 前綴形式>所有滿足前綴的接口ID會被引入對象,并取其后半部分作為方法名
ModelProxy.create( 'Search.*' );

同時(shí),使用這些Model,你可以很輕易地實(shí)現(xiàn)合并請求或者依賴請求,并做相關(guān)模板渲染

【例二】 合并請求

var model = new ModelProxy( 'Search.*' );

// 合并請求 (下面調(diào)用的model方法除done之外,皆為配置接口id時(shí)指定)
model.suggest( { q: '女' } )
    .list( { keyword: 'iphone6' } )
    .getNav( { key: '流行服裝' } )
    .done( function( data1, data2, data3 ) {
        // 參數(shù)順序與方法調(diào)用順序一致
        console.log( data1, data2, data3 );
    } );

【例三】 依賴請求

var model = new ModelProxy( {
    getUser: 'Session.getUser',
    getMyOrderList: 'Order.getOrder'
} );
// 先獲得用戶id,然后再根據(jù)id號獲得訂單列表
model.getUser( { sid: 'fdkaldjfgsakls0322yf8' } )
    .done( function( data ) {
        var uid = data.uid;
        // 二次數(shù)據(jù)請求依賴第一次取得的id號
        this.getMyOrderList( { id: uid } )
            .done( function( data ) {
                console.log( data );
            } );
    } );

此外ModelProxy不僅在Node端可以使用,也可以在瀏覽器端使用。只需要在頁面中引入官方包提供的modelproxy-client.js即可。
【例四】瀏覽器端使用ModelProxy

<!-- 引入modelproxy模塊,該模塊本身是由KISSY封裝的標(biāo)準(zhǔn)模塊-->
<script src="modelproxy-client.js" ></script>
<script type="text/javascript">
    KISSY.use( "modelproxy", function( S, ModelProxy ) {
        // !配置基礎(chǔ)路徑,該路徑與第二步中配置的攔截路徑一致!
        // 且全局配置有且只有一次!
        ModelProxy.configBase( '/model/' );

        // 創(chuàng)建model
        var searchModel = ModelProxy.create( 'Search.*' );
        searchModel
            .list( { q: 'ihpone6' } )
            .list( { q: '沖鋒衣' } )
            .suggest( { q: 'i' } )
            .getNav( { q: '滑板' } )
            .done( function( data1, data2, data3, data4 ) {
                console.log( {
                    "list_ihpone6": data1,
                    "list_沖鋒衣": data2,
                    "suggest_i": data3,
                    "getNav_滑板": data4
                } );
            } );
    } );
</script>

同時(shí),ModelProxy可以配合Midway另一核心組件Midway-XTPL一起使用,實(shí)現(xiàn)數(shù)據(jù)和模板以及相關(guān)渲染過程在瀏覽器端和服務(wù)器端的全共享。關(guān)于ModelProxy的詳細(xì)教程及文檔請移步https://github.com/purejs/modelproxy

總結(jié)

ModelProxy以一種配置化的輕量級框架存在,提供友好的接口model組裝及使用方式,同時(shí)很好的解決前后端開發(fā)模式分離中的接口使用規(guī)范問題。在整個(gè)項(xiàng)目開發(fā)過程中,接口始終只需要定義描述一次,前端開發(fā)人員即可引用,同時(shí)使用River工具自動(dòng)生成文檔,形成與后端開發(fā)人員的契約,并做相關(guān)自動(dòng)化測試,極大地優(yōu)化了整個(gè)軟件工程開發(fā)過程。

【注】River 是阿里集團(tuán)研發(fā)的前后端統(tǒng)一接口規(guī)范及相關(guān)工具集合的統(tǒng)稱

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號