1. 程式人生 > >Node.js框架之express與koa對比分析

Node.js框架之express與koa對比分析

提到Node.js開發,不得不提目前炙手可熱的2大框架express和koa。Express誕生已有時日,是一個簡潔而靈活的web開發框架,使用簡單而功能強大。Koa相對更為年輕,是Express框架原班人馬基於ES6新特性重新開發的敏捷開發框架,現在可謂風頭正勁,大有趕超Express之勢。

Express和koa都是服務端的開發框架,服務端開發的重點是對HTTP Request和HTTP Response兩個物件的封裝和處理,應用的生命週期維護以及檢視的處理等。 以下將主要通過這些方面,對兩者進行一個對比介紹,看看到底有什麼區別。

Express主要基於Connect中介軟體框架,功能豐富,隨取隨用,並且框架自身封裝了大量便利的功能,比如路由、檢視處理等等。而koa主要基於co中介軟體框架,框架自身並沒整合太多功能,大部分功能需要使用者自行require中介軟體去解決,但是由於其基於ES6 generator特性的中介軟體機制,解決了長期詬病的“callback hell”和麻煩的錯誤處理的問題,大受開發者歡迎。

Express和koa初印象

先來一個Hello World,各自認識一下吧

//Express
var express = require('express')
var app = express()  //建立一個APP例項

//建一個專案根目錄的get請求路由,回撥方法中直接輸出字串Hello World!
app.get('/', function (req, res) {
    res.send('Hello World!')
});

//監聽埠,啟動服務
app.listen(3000);
//Koa
var koa = require('koa');
var route = require('koa-route'
); //koa預設沒有整合route功能,引入中介軟體 var app = koa(); //建立一個APP例項 //建一個專案根目錄的get請求路由,回撥方法中直接輸出字串Hello World!,就是掛載一箇中間件 app.use(route.get('/', function *(){ this.body = 'Hello World'; })); //監聽埠,啟動服務 app.listen(3000);

可以看出來,兩者建立一個基礎的Web服務都非常簡單,可以說幾行程式碼就解決了問題。兩者的寫法也基本相同,最大的區別是路由處理Express是自身整合的,而koa需要引入中介軟體。以下是Koa官方文件對於兩者特性的一個對比:

重要功能對比介紹

Feature Koa Express Connect
Middleware Kernel
Routing
Templating
Sending Files
JSONP

通過後續的比較,大家其實可以看出,雖然koa看上去比express少集成了很多功能,但是使用起來其實基本一致,因為中介軟體非常豐富全面,需要什麼require進來就行了(不一定要像express那樣先幫你require好),使用起來反而更加靈活。

應用生命週期和上下文

我們在專案過程中,經常需要用到在整個應用生命週期中共享的配置和資料物件,比如服務URL、是否啟用某個功能特性、介面配置、當前登入使用者資料等等。屬於比較基礎的功能,兩者都非常方便,koa的application context感覺使用起來更方便一點。

//Express
//共享配置,express提供了很多便利的方法
app.set('enableCache', true)
app.get('enableCache')//true

app.disable('cache')
app.disabled('cache')//true

app.enable('cache')
app.enabled('cache')//true

//應用共享資料:app.locals
app.locals.user = {name:"Samoay", id:1234};
//Koa
//配置,直接使用koa context即可
app.enableCache = true;

app.use(function *(next){
    console.log(this.app.enableCache);
    //true
    this.app.enableCache = false;

    //just use this
    this.staticPath = 'static';

    yield *next;
});

//應用共享資料:ctx.state
this.state.user = {name:"Samoay", id:1234};

請求 HTTP Request

伺服器端需要進行什麼處理,怎麼處理以及處理的引數都依賴客戶端傳送的請求,兩個框架都封裝了HTTP Request物件,便於對這一部分進行處理。以下主要舉例說明下對請求引數的處理,其它例如頭資訊、Cookie等請參考官方文件。兩者除了寫法上稍有區別,沒太大區別。GET引數都可以直接通過Request物件獲取,POST引數都需要引入中介軟體先parse,再取值。

// Express
// 獲取QueryString引數
// GET /shoes?order=desc&shoe[color]=blue
req.query.order
// => "desc"

req.query.shoe.color
// => "blue"

// 通過路由獲取Restful風格的URL引數
app.get('/user/:id?', function userIdHandler(req, res) {
    console.log(req.params.id);
    res.send('GET');
})

//獲取POST資料:需要body-parser中介軟體
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/', function (req, res) {
    console.log(req.body);
    res.json(req.body);
})
// 獲取QueryString引數
// GET /?action=delete&id=1234
this.request.query
// => { action: 'delete', id: '1234' }

// 通過路由獲取Restful風格的URL引數
var route = require('koa-route');
app.use(route.get('/post/:id', function *(id){
    console.log(id);
    // => 1234
}));

// 獲取POST資料:需要co-body中介軟體
// Content-Type: application/x-www-form-urlencoded
// title=Test&content=This+is+a+test+post
var parse = require('co-body');
app.use(route.post('/post/new', function *(){
    var post = yield parse(this.request);//this
    console.log(post);
    // => { title: 'Test', content: 'This is a test post' }
}));

路由 Route

收到客戶端的請求,服務需要通過識別請求的方法(HTTP Method: GET, POST, PUT...)和請求的具體路徑(path)來進行不同的處理。這部分功能就是路由(Route)需要做的事情,說白了就是請求的分發,分發到不同的回撥方法去處理。

// Express
// app.all表示對所有的路徑和請求方式都要經過這些回撥方法的處理,可以逗號方式傳入多個
app.all('*', authentication, loadUser);
// 也可以多次呼叫
app.all('*', requireAuthentication)
app.all('*', loadUser);
// 也可以針對某具體路徑下面的所有請求
app.all('/api/*', requireAuthentication);

// app.get GET方式的請求
app.get('/user/:id', function(req, res) {
    res.send('user ' + req.params.id);
});

// app.post  POST方式的請求
app.post('/user/create', function(req, res) {
    res.send('create new user');
});

這裡需要說明2個問題,首先是app.get,在應用生命週期中也有一個app.get方法,用於獲取專案配置。Express內部就是公用的一個方法,如果傳入的只有1個引數就獲取配置,2個引數就作為路由處理。其次是app.use('*', cb) 與app.all('*', cb) 的區別,前者是中介軟體方式,呼叫是有順序的,不一定會執行到;後者是路由方式,肯定會執行到。

// Koa
// 和Express不同,koa需要先引入route中介軟體
var route = require('koa-route');

//引入中介軟體之後支援的寫法差不多,只是路徑傳入route,然後把route作為中介軟體掛載到app
app.use(route.get('/', list));
app.use(route.get('/post/new', add));
app.use(route.get('/post/:id', show));
app.use(route.post('/post', create));

//鏈式寫法
var router = require('koa-router')();

router.get('/', list)
      .get('/post/new', add)
      .get('/post/:id', show)
      .post('/post', create);

app.use(router.routes())
   .use(router.allowedMethods());

檢視 Views

Express框架自身集成了檢視功能,提供了consolidate.js功能,可以是有幾乎所有Javascript模板引擎,並提供了檢視設定的便利方法。Koa需要引入co-views中介軟體,co-views也是基於consolidate.js,支援能力一樣強大。

// Express
// 這隻模板路徑和預設的模板字尾
app.set('views', __dirname + '/tpls');
app.set('view engine', 'html');

//預設,express根據template的字尾自動選擇模板
//引擎渲染,支援jade和ejs。如果不使用預設副檔名
app.engine(ext, callback)

app.engine('html', require('ejs').renderFile);

//如果模板引擎不支援(path, options, callback)
var engines = require('consolidate');
app.engine('html', engines.handlebars);
app.engine('tpl', engines.underscore);

app.get('list', function(res, req){
    res.render('list', {data});
});
//Koa
//需要引入co-views中介軟體
var views = require('co-views');

var render = views('tpls', {
    map: { html: 'swig' },//html字尾使用引擎
    default: "jade"//render不提供字尾名時
});

var userInfo = {
    name: 'tobi',
    species: 'ferret'
};

var html;
html = render('user', { user: userInfo });
html = render('user.jade', { user: userInfo });
html = render('user.ejs', { user: userInfo });

返回 HTTP Response

獲取完請求引數、處理好了具體的請求、檢視也準備就緒,下面就該返回給客戶端了,那就是HTTP Response物件了。這部分也屬於框架的基礎部分,各種都做了封裝實現,顯著的區別是koa直接將輸出繫結到了ctx.body屬性上,另外輸出JSON或JSONP需要引入中介軟體。

// Express
//輸出普通的html
res.render('tplName', {data});

//輸出JSON
res.jsonp({ user: 'Samoay' });
// => { "user": "Samoay" }

//輸出JSONP   ?callback=foo
res.jsonp({ user: 'Samoay' });
// => foo({ "user": "Samoay" });

//res.send([body]);
res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');

//設定HTTP Status狀態碼
res.status(200);
//koa直接set ctx的status和body
app.use(route.get('/post/update/:id', function *(id){
    this.status = 404;
    this.body = 'Page Not Found';
}));

var views = require('co-views');
var render = views('tpls', {
    default: "jade"//render不提供字尾名時
});
app.use(route.get('/post/:id', function *(id){
    var post = getPost(id);
    this.status = 200;//by default, optional
    this.body = yield render('user', post);
}));

//JSON
var json = require('koa-json');
app.use(route.get('/post/:id', function *(id){
    this.body = {id:1234, title:"Test post", content:"..."};
}));

中介軟體 Middleware

對比了主要的幾個框架功能方面的使用,其實區別最大,使用方式最不同的地方是在中介軟體的處理上。Express由於是在ES6特性之前的,中介軟體的基礎原理還是callback方式的;而koa得益於generator特性和co框架(co會把所有generator的返回封裝成為Promise物件),使得中介軟體的編寫更加優雅。

// req 用於獲取請求資訊, ServerRequest 的例項
// res 用於響應處理結果, ServerResponse 的例項
// next() 函式用於將當前控制權轉交給下一步處理,
//        如果給 next() 傳遞一個引數時,表示出錯資訊
var x = function (req, res, next) {

    // 對req和res進行必要的處理

    // 進入下一個中介軟體
    return next();

    // 傳遞錯誤資訊到下一個中介軟體
    return next(err);

    // 直接輸出,不再進入後面的中介軟體
    return res.send('show page');
};
// koa 一切都在ctx物件上+generator
app.use(function *(){
    this; // is the Context

    this.request; // is a koa Request
    this.response; // is a koa Response

    this.req;// is node js request
    this.res;// is node js response

    //不再進入後面的中介軟體, 回溯upstream
    return;
});

相關推薦

Node.js框架expresskoa對比分析

提到Node.js開發,不得不提目前炙手可熱的2大框架express和koa。Express誕生已有時日,是一個簡潔而靈活的web開發框架,使用簡單而功能強大。Koa相對更為年輕,是Express框架原班人馬基於ES6新特性重新開發的敏捷開發框架,現在可謂風頭正勁,大有趕超Express之勢。 Exp

Node.js歷險記express框架入門篇

開啟微信掃一掃,關注微信公眾號【資料與演算法聯盟】 轉載請註明出處:http://blog.csdn.net/gamer_gyt 博主微博:http://weibo.com/234654758 Github:https://github.com/

Node.js框架Egg.js

Node.js是我前段時間接觸的一個JavaScript的服務端語言,感覺還是挺有意思的。 也許有人說,你學這麼多,學的過來嗎?或者說學的太多,專而不精,有必要這樣嗎? 其實,我個人認為,自從我進入IT界以來,我覺得對於程式設計或者是一些框架,我過去是被迫學習,現在是主動學習。其實之所以想學這麼多,除了為

expresskoa對比

使用體驗 koa const Koa = require('koa'); const app = new Koa(); app.use(ctx => { ctx.body = 'Hello Koa'; }); app.listen(

node.js上除了Express還有哪些好用的web開發框架

短連接 還要 搭建 ews rect 所有 感到 差異 iss 老司機都有體會, 開發本身沒有多難, 最糾結其實是最初的技術和框架選型, 本沒有絕對的好壞之分, 可一旦選擇了不適合於自己業務場景的框架, 將來木已成舟後開發和維護成本都很高, 等發現不合適的時候更換的

Node.js學習旅(二)-----MongoDB的安裝啟動

tar 商業 blank script img blog javascrip ref es2017 安裝與啟動MongoDB Windows 用戶向導:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-

130行實現Express風格的Node.js框架

很多時候我們使用Express,只是用到了它方便的路由和中介軟體系統。其實這個功能我們用一百多行程式碼可以輕鬆實現,且沒有任何依賴,而不必專門引入Express。 我們先來分析一下需求,我們要做的是一個路由系統,書寫的方式為: //路由系統 app.method(path, handle

centos7安裝node.js框架配置環境變數

node官方網站下載解壓  https://nodejs.org 目錄/檔案 說明 ./ 根目錄,我們的node.js程式碼都會放在這個目錄 package.json npm依賴配置檔案

Node.js開發入門—Express安裝使用

之前我們在安裝完Node.js後直接寫了個HelloWorld網站,這次呢,我們使用Node.js的Web框架Express來重寫一下HelloWorld,看看有什麼不同。同時我們還會重寫之前的檔案伺服器,功能更完善而程式碼更簡潔。 安裝 express

Node.js原生及Express方法實現註冊登錄原理

美化 set head ack function charset stat input col 由於本文只是實現其原理,所以沒有使用數據庫,只是在js裏面模擬數據庫,當然實際中還是需要用數據庫的。 1.node.js原生方法 ①html頁面,非常簡單,沒有一絲美化~我們叫它

Node.js的循環異步問題

文件的 call 讓我 cti fin 輸出結果 退出 -i ack Node.js 的異步機制由事件和回調函數實現,一開始接觸可能會感覺違反常規,但習慣  以後就會發現還是很簡單的。然而這之中其實暗藏了不少陷阱,一個很容易遇到的問題就是  循環中的回調函數,初學者經常容易

4. Beego 框架cookiesession

文件夾 emca 添加 入口 on() eth string mysql func what is cookie? cookie是存儲在客戶端的,用於標識客戶身份的! what is session session 是存儲在服務端,也是用於客戶身份標識,用於跟蹤用戶會話。

實現動畫CSSJavaScript對比

運行時 理解 controls 進行 中間 PE osi 聰明人 為什麽 曾經某個時期,大多數開發者使用 jQuery 給瀏覽器中的元素添加動畫。讓這個淡化,讓那個擴大,很簡單。隨著互動的項目越來越復雜,移動設備的大量增加,表現性能變得越來越重要。Flash 被拋棄,有天賦

Android框架VolleyGlide

cat name 圖片緩存 上傳文件 bsp 怎麽 每一個 ons exc PS:在看到這個題目的同時,你們估計會想,Volley與Glide怎麽拿來一塊說呢,他們雖然不是一個框架,但有著相同功能,那就是圖片處理方面。首先我們先來看一下什麽volley,又什麽是glide。

Java基礎知識(JAVA集合框架ListSet)

開發 如果 表數 特點 必須 加鎖 以及 stringbu 不可 List和Set概述數組必須存放同一種元素。StringBuffer必須轉換成字符串才能使用,如果想拿出單獨的一個元素幾乎不可能。數據有很多使用對象存,對象有很多,使用集合存。 集合容器因為內部

node.js學習簡易httpserver的搭建

先說一下這個簡易伺服器所能實現的功能: 實現一個簡單的使用者登入、註冊。 直接上圖: 1.(沒有註冊之前點選登入的效果) 2.(點選註冊時的截圖如下) 3.(輸入正確的使用者名稱密碼,點選登入時的介面) 4.(輸入錯誤的密碼,點選登入): 以下是伺服器的具體程式碼:

Node.js線上伺服器部署釋出

第1章 課程預熱對整個部署思路進行全流程介紹,通過 5 個不同型別專案,來演示從本地的倉庫到最終線上穩定執行的整個專案部署釋出流程,來幫助始終程式設計在一線的前端或者後端工程師,甚至是有 Coding 能力的產品經理,從操作流程和架構形態上,掌握從零開始的專案上線環節,掌握這關鍵一步,跨過去前端到後端,本地到

Nest.js 5.4.1 釋出,支援微服務的 AOP 風格 Node.js 框架

   Nest.js 是用於構建高效且可伸縮 Web 應用程式的漸進式 Node.js 框架。 完美支援 Typescript 面向 AOP 程式設計 支援 typeorm Node.js 版的 spring 構建微服務應用 本次更新如下: Bug修復 核心:

部署onlyoffice(node.js版本)野蠻施工法

OnlyOffice,線上的文件編輯工具,可以在瀏覽器上建立WORD,EXCEL,PPT,並且實現線上編輯功能。 第一步,使用docker安裝OnlyOffice/DocumentServer. sudo docker pull onlyoffice/documentserv

Nest.js 5.5 釋出,最近火的一P的node.js 框架

   Nest 釋出一年(以釋出第一個版本為限)便超過 10000 star ,目前每月下載量超過 230k Nest.js 是用於構建高效且可伸縮 Web 應用程式的漸進式 Node.js 框架。 完美支援 Typescript 面向 AOP 程式設計 支援 type