内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

淺析Express中的路由與應(yīng)用模式-創(chuàng)新互聯(lián)

1. 引言

Express是一個(gè)基于Node.js的輕量級(jí)web開發(fā)框架,具有體積小,使用靈活等特點(diǎn)。查看Express的源碼,如果不計(jì)供使用的中間件,主體框架只有一千余行代碼,非常簡(jiǎn)練。

目前創(chuàng)新互聯(lián)建站已為超過千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、雅安服務(wù)器托管、網(wǎng)站改版維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、習(xí)水網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

Express模型的核心為Express中定義的路由和路由器。分析Express源碼可發(fā)現(xiàn)Express的路由提供多種靈活的應(yīng)用模式。

我們首先介紹一下Express中的路由、路由器相關(guān)概念、結(jié)構(gòu)及其特點(diǎn),然后針對(duì)典型場(chǎng)景描述使用Express路由的四種應(yīng)用模式。

2.Express中的路由與路由器

Express具有典型的MVC模型特征。我們將路由定義為一個(gè)二元組route=(path, endpoint):其中path為HTTP請(qǐng)求的路徑,endpoint為請(qǐng)求路徑應(yīng)映射到的端點(diǎn)(端點(diǎn)可視為處理該請(qǐng)求的實(shí)體),則Express中的路由器負(fù)責(zé)將請(qǐng)求映射到對(duì)應(yīng)端點(diǎn)進(jìn)行處理。

Express中的路由器分為兩種類型:

app類型的路由器常使用如下代碼創(chuàng)建:

var express = require('express');
var app = express();

router類型的路由器常使用如下代碼創(chuàng)建:

var express = require('express');
var router = express.Router();

app和router是形為function(request, response, next)形式的函數(shù)對(duì)象,使用app.verb(),router.verb()形式函數(shù)實(shí)現(xiàn)路由注冊(cè)(路由注冊(cè)本質(zhì)上是一個(gè)觀察者模式)。

app.verb()和router.verb()中的verb常使用use、get、post、put、delete、route等動(dòng)詞,不同動(dòng)詞管轄的HTTP請(qǐng)求方法范圍不同,這些動(dòng)詞函數(shù)的參數(shù)形式常為(pathExp, handleCallback)形式:其中pathExp表示請(qǐng)求路徑,可為正則表達(dá)式;handleCallback為路徑映射處理函數(shù)。

app是Express框架所構(gòu)建程序的請(qǐng)求處理入口,app可作為頂層路由器使用,在應(yīng)用中也可掛載下級(jí)路由器(使用router對(duì)象)以實(shí)現(xiàn)分級(jí)路由。其間的關(guān)系可由下圖表示:

淺析Express中的路由與應(yīng)用模式

考察如下代碼:

app.use('/reports', router1);
router1.get('/querymysql/:id', queryMysqlData, handleQueryData);

對(duì)于http請(qǐng)求URL“/reports/querymysql/1”,Express中的路由器將此請(qǐng)求路由到queryMysqlData函數(shù)處理。


3.     Express中的路由應(yīng)用模式

3.1.  REST模式

對(duì)于一個(gè)使用restful風(fēng)格的應(yīng)用, 讓我們想一想在不使用Express的時(shí)候如何在Node.js中處理rest請(qǐng)求,我們常常會(huì)寫下如下示例代碼:

var server = http.createServer(function (request, response) {
     switch (request.url) {
                    case 'uri1'
                        handleUri1 (request, response);
                        break;
                    case ' uri2'
                        handleU ri2(request, response);
                        break;
                    case ' uri3'
                        handleU ri3 (request, response);
                        break;
 
                    case ' uri4'
                        handleU ri4 (request, response);
                        break;
                    ...
                    default:
                        logToConsole('unknown path:' + path);
                        response.writeHead(404);
                        response.end("404 Not found");
                        break;
                }
}

Express將上面代碼中對(duì)每個(gè)rest資源的操作(switch分支)轉(zhuǎn)換為路由,路由中的路徑為rest資源的URI,處理端點(diǎn)為function(request, response, next)形式、對(duì)rest資源的操作函數(shù)。

常使用app.route函數(shù)實(shí)現(xiàn)一個(gè)完整的restful接口,如下示例代碼:

app.route('/uri1')
  .get(function(req, res) {
    handleGetUri1();
  })
  .post(function(req, res) {
    handlePost Uri1 ();
  })
  .put(function(req, res) {
    handlePut Uri 1();
  })
.delete(function(req, res) {
    handleDeleteUri 1();
  });

3.2.  AOP模式

在處理不同路徑的HTTP請(qǐng)求時(shí),常常需要在請(qǐng)求處理前和處理后做一些通用操作,這種應(yīng)用需求是一個(gè)典型的AOP應(yīng)用要求。

Express中允許定義一個(gè)具有通配路徑的路由,在調(diào)用其它路徑的路由前會(huì)先調(diào)用該通配路徑路由。此通配路徑路由也成為其它路徑路由切面的一個(gè)注入點(diǎn),考察如下示例代碼:

router.use(function timelog(req,res,next){
    console.log("receive report request time is:",Date.now());
    next(); //注意next函數(shù)的使用,必須聲明該函數(shù)才能調(diào)用后繼映射函數(shù)
});
 
router.get('/chart1', proxy({
    target: 'http://127.0.0.1:8082',
    changeOrigin: true,
    pathRewrite: {
        '^/reports/chart1': '/loadChart1'
    }
}));
 
router.get('/querymysql/:id', queryMysqlData, handleQueryData);

上述代碼中,在執(zhí)行router的'/chart1'路由和'/querymysql/:id'路由之前都會(huì)執(zhí)行timelog函數(shù),在日志中記錄當(dāng)前路由執(zhí)行時(shí)間。

3.3.  責(zé)任鏈模式

在Node.js中,由于多使用異步函數(shù),常會(huì)出現(xiàn)異步回調(diào)函數(shù)中嵌套異步回調(diào)函數(shù)的情形。當(dāng)出現(xiàn)多重異步回調(diào)時(shí),則代碼會(huì)變得混亂和難以維護(hù)。

考察一個(gè)應(yīng)用場(chǎng)景:應(yīng)用需要在數(shù)據(jù)庫中進(jìn)行多次查詢,并對(duì)多次查詢的結(jié)果綜合處理。若使用數(shù)據(jù)庫提供的異步查詢接口,則需要在前一個(gè)查詢操作的回調(diào)函數(shù)中進(jìn)行下一個(gè)查詢操作,若寫在一個(gè)回調(diào)函數(shù)中,代碼顯臃腫。

Express的一個(gè)路由可定義多個(gè)處理函數(shù),這些處理函數(shù)可設(shè)計(jì)為鏈?zhǔn)秸{(diào)用,實(shí)現(xiàn)了責(zé)任鏈模式,考察如下代碼:

app.get('/test',function(req,res,next){
    handle1();
    next();
},function(req,res,next){
    handle2();
    next();
},function(req,res,next){
   handle3();
});

上述代碼中:handle1, handle2, handle3構(gòu)成了一個(gè)處理責(zé)任鏈“handle1->handle2->handle3”,通過next函數(shù)指引鏈?zhǔn)秸{(diào)用。

Express中路由的責(zé)任鏈應(yīng)用特性使得多重異步嵌套的代碼變得清晰和優(yōu)雅。

   針對(duì)本節(jié)開始提到的數(shù)據(jù)庫查詢應(yīng)用場(chǎng)景,下面的示例代碼展示了責(zé)任鏈模式的應(yīng)用特點(diǎn)。

router.get('/querymysql/:id', queryMysqlData, handleQueryData);
 
//查詢mysql表中的數(shù)據(jù)
function queryMysqlData(req, res, next) {
    if ("id" in req.params) {
        dbpool.query(" select * from articles where id=?" ,[req.params.id], function (err, rows, fields) {
            if (err) {
                res.send(err.stack);
            } else {
                if (rows && rows.length > 0) {
                    console.log('The queried rows is: ', rows.length);
                    res.articles = rows;
                    next();
                } else {
                    res.send("no query results!");
                }
            }
        });
    } else {
        res.send("invalid query params!");
    }
}
 
//處理查詢mysql后得到的數(shù)據(jù)
function handleQueryData(req, res) {
    if ("articles" in res) {
        res.send("id:" + req.params.id + ";title:" + res.articles[0].title);
    }else{
        res.send("no query data handled!");
    }
}

3.4.  熔斷器模式

上節(jié)提到的責(zé)任鏈模式本質(zhì)上是一個(gè)逐級(jí)調(diào)用模型。在分布式服務(wù)架構(gòu)(微服務(wù)架構(gòu))中,深度調(diào)用常常需要考慮調(diào)用可達(dá)性問題,即需要考慮某級(jí)調(diào)用會(huì)否一直不響應(yīng)。調(diào)用可達(dá)性問題常使用熔斷器模式,即在調(diào)用端設(shè)置一個(gè)熔斷器,熔斷條件產(chǎn)生時(shí),熔斷器發(fā)生熔斷,返回給調(diào)用方調(diào)用失敗信息。

考慮這樣的應(yīng)用場(chǎng)景:對(duì)于一些有處理時(shí)間要求的請(qǐng)求,當(dāng)在指定時(shí)間內(nèi)沒有完成處理,需要向請(qǐng)求方返回處理失敗信息。針對(duì)此應(yīng)用場(chǎng)景,可在Express路由中設(shè)置超時(shí)熔斷器,當(dāng)處理超時(shí),開啟熔斷器,通知請(qǐng)求方本次處理請(qǐng)求失敗。

上述應(yīng)用場(chǎng)景可使用如下示例代碼應(yīng)對(duì):

app.get('/circuit',function(req, res, next){
    var bt=setTimeout(function () {
        next('route'); //觸發(fā)熔斷
    },3000); //設(shè)置熔斷時(shí)間為3秒
   res.breakTimer = bt;
   next();
},function(req,res,next){
    handle2();
    next();
},function(req,res,next){
   handle3();
   clearTimeout(res.breakTimer);//正常執(zhí)行完畢,取消熔斷定時(shí)器
});
 
app.get('/circuit ',function(req,res,next){
  if(!res.finished){ //如果還沒有響應(yīng),啟動(dòng)熔斷
    //返回給調(diào)用者熔斷信息
    res.send("breakCondition is true, notify the invoker.");
  }
});

4.     小結(jié)

本文介紹了Express框架中路由和路由器的概念、結(jié)構(gòu)和特點(diǎn),并針對(duì)典型應(yīng)用場(chǎng)景歸納了REST、AOP、責(zé)任鏈、熔斷器四種應(yīng)用模式,可用于應(yīng)用開發(fā)中的一些常用場(chǎng)景。

5.     參考文獻(xiàn)

  1.  http://expressjs.com/

  2. http://www.runoob.com/


另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

本文題目:淺析Express中的路由與應(yīng)用模式-創(chuàng)新互聯(lián)
標(biāo)題來源:http://www.rwnh.cn/article44/ddohhe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、網(wǎng)站營銷網(wǎng)站內(nèi)鏈App設(shè)計(jì)、域名注冊(cè)外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)
广宗县| 天镇县| 托克托县| 建始县| 柏乡县| 屏东市| 英山县| 汶川县| 石城县| 洱源县| 黄平县| 沈阳市| 荣昌县| 鲁甸县| 加查县| 乌拉特中旗| 汉中市| 茌平县| 芮城县| 嘉定区| 顺昌县| 石棉县| 砀山县| 广饶县| 汾阳市| 新密市| 福泉市| 德兴市| 仙桃市| 松潘县| 保定市| 启东市| 曲麻莱县| 保德县| 赣榆县| 高密市| 咸丰县| 盈江县| 南陵县| 明溪县| 筠连县|