Node.js框架對比:Express/Koa/Hapi

Node.js框架對比:Express/Koa/Hapi

 

引言

Express.js是當今使用最廣泛的Node.js Web應用程序框架。它似乎是大多數Node.js Web應用程序中的基本依賴項,即使某些流行的框架(如Sails.js)也是基於Express構建的。但是,有更多選項對他們具有相同的“ sinatra風格”感覺。接下來的兩個最受歡迎的框架分別是Koa和Hapi。

這並不是說服您使用一個框架,而是要幫助您更好地瞭解每個框架可以做什麼以及在什麼地方可能勝過另一個框架。

 

框架背景

我們將要研究的所有三個框架都有很多共同點。所有人都可以只用幾行代碼就可以創建服務器,而且一切都使得創建REST API非常簡單。讓我們看看這些框架是如何開始的。

 

2.1 Express

TJ Holowaychuk於2009年6月26日對Express進行了最初的提交,而2010年1月2日發佈了660則0.0.1版的更新。當時的兩個主要貢獻者是TJ和Ciaron Jessup。在第一個發行版時,該框架根據github上的readme.md進行了描述。

建立在node.jsV8 JavaScript引擎之上的快速(小型)服務器端JavaScript Web開發框架。

快進近5年,提交4,925次提交,現在4.10.1是StrongLoop維護的最新版本,因爲TJ現在正集中在Go-Lang社區中。

 

2.2 Koa

對Koa的最初承諾是在一年多以前,即2013年8月17日,當時TJ Holowaychuk對此毫無保留。他將其描述爲“用於通過使用co生成器的nod​​e.js的表達中間件,使編寫Web應用程序和REST API的編寫更加令人愉快”。宣傳Koa的足跡很小,約爲400 SLOC。現在,它在0.13.0版本中有585次提交。

 

2.3 Hapi

Hapi的最初提交是在2011年8月5日,由WalmartLabs的成員Eran Hammer進行。Hapi由Postmile的一部分創建,最初是在Express之上構建的。後來由於Erin state在他的博客中的內容,它被開發成自己的框架:

創建hapi的想法是配置比代碼更好業務邏輯必須與傳輸層隔離 ...

3,816次提交,以後Hapi的版本爲7.2.0,仍由Eran Hammer維護。

最後,讓我們看看一些社區統計數據,以瞭解這些框架的受歡迎程度:

  

參考項

Express.js

Koa.js

Hapi.js

Github點贊數

16158

5846

3283

代碼貢獻者

163

49

95

依賴包數量

3828

99

102

StackOverFlow提問數

11419

72

82

 

創建服務器

對於任何開發人員而言,在使用Node.js Web應用程序時,第一步是創建一個基本服務器。因此,讓我們使用每個框架創建一個服務器來查看它們的異同。

 

3.1 快遞

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

var server = app.listen(3000, function() {
    console.log('Express is listening to http://localhost:3000');
});

對於所有節點開發人員來說,這可能是很自然的。我們需要express,然後通過將其分配給變量來實例化它app。然後實例化服務器以監聽端口3000。app.listen()實際上,它實際上只是節點的包裝http.createServer()

 

3.2 Koa

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

var server = app.listen(3000, function() {
    console.log('Koa is listening to http://localhost:3000');
}); 

馬上,您會看到Koa與Express相似。本質上,您只需要koa而不是express。也app.listen()與Express中使用的包裝器功能完全相同。

 

3.3哈皮

var Hapi = require('hapi');
var server = new Hapi.Server(3000);

server.start(function() {
    console.log('Hapi is listening to http://localhost:3000');
});

哈皮(Hapi)是該集團中獨一無二的一家。首先,像往常一樣,需要hapi app,而不是實例化hapi ,而是創建一個新的Server並指定端口。在Express和Koa中,我們獲得了一個回調函數,而在Hapi中,我們獲得了一個新server對象。然後,一旦調用,server.start()我們就在端口3000上啓動服務器,然後返回回調。但是,這不像Koa和Express,它不是包裝器http.CreateServer(),而是使用了自己的邏輯。

 

路由

現在,讓我們深入探討服務器最重要的功能之一,即路由。首先,讓我們爲每個框架創建俗套的“ Hello world”應用程序,然後繼續使用其他有用的REST API。

 

4.1Hello World

 

4.1.1快遞

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

app.get('/', function(req, res) {
    res.send('Hello world');
});

var server = app.listen(3000, function() {
    console.log('Express is listening to http://localhost:3000');
});

我們正在使用該get()方法來捕獲傳入的“ GET /”請求,然後調用處理兩個參數req和的回調函數res。在此示例中,我們僅利用res來將字符串返回給頁面res.send()。Express具有用於處理路由功能的多種內置方法。下面是一些由快遞支持的較常用的方法(但不是所有的方法)getpostputheaddelete...

 

4.1.2 Koa

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

app.use(function *() {
    this.body = 'Hello world';
});

var server = app.listen(3000, function() {
    console.log('Koa is listening to http://localhost:3000');
});

Koa與Express略有不同,它使用的是ES6生成器。任何以“。”開頭*的函數都將返回一個生成器對象。基本上,這些生成器會yield同步值,但這超出了本文的範圍。在app.use()generator函數內設置響應主體。在Koa中Context,等同於this標識符的是節點requestresponse對象的封裝。 this.body是Koa Response對象中的方法。 this.body可以設置爲字符串,緩衝區,流,對象或null。在這個示例中,我們使用了Koa核心中提供的少數中間件之一。我們使用的這個中間件捕獲所有路由並以提供的字符串進行響應。

4.1.3哈皮

var Hapi = require('hapi');
var server = new Hapi.Server(3000);

server.route({
    method: 'GET',
    path: '/',
    handler: function(request, reply) {
        reply('Hello world');
    }
});

server.start(function() {
    console.log('Hapi is listening to http://localhost:3000');
});

在這裏,我們使用該server對象提供給我們的內置方法,該方法server.route()具有以下選項:( path必需),method(必需)vhost,和handler(必需)。HTTP方法可以處理典型請求GETPUTPOSTDELETE,和*其抓住的任何途徑。處理程序將傳遞對該request對象的引用,並且必須reply使用包含的有效負載進行調用。有效負載可以是字符串,緩衝區,可序列化的對象或流。

 

4.2 REST API

除了顯示最基本/最簡單的啓動和運行應用程序的方式外,Hello世界從沒有真正做過什麼。REST API在所有數據密集型應用程序中幾乎都是必需的,並且將有助於更好地瞭解如何使用這些框架。因此,讓我們看一下它們如何處理REST API。

 

4.2.1快遞

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

// REST API
router.route('/items')
.get(function(req, res, next) {
  res.send('Get');
})
.post(function(req, res, next) {
  res.send('Post');
});

router.route('/items/:id')
.get(function(req, res, next) {
  res.send('Get id: ' + req.params.id);
})
.put(function(req, res, next) {
  res.send('Put id: ' + req.params.id);
})
.delete(function(req, res, next) {
  res.send('Delete id: ' + req.params.id);
});

app.use('/api', router);

// index
app.get('/', function(req, res) {
  res.send('Hello world');
});

var server = app.listen(3000, function() {
  console.log('Express is listening to http://localhost:3000');
});

因此,我們將REST API添加到了現有的Hello World應用程序中。Express提供了一些處理路線的捷徑。這是Express 4.x語法,但在Express 3.x中基本上相同,除了不需要,express.Router()並且將無法使用該行app.use('/api', router)。相反,您將在現有動詞之前router.route()加上來替換的。這是一個很好的方法,因爲它減少了開發人員出錯的機會,並最小化了更改HTTP方法動詞的位置。app.route()/api

 

4.2.2 Koa

var koa = require('koa');
var route = require('koa-route');
var app = koa();

// REST API
app.use(route.get('/api/items', function*() {
    this.body = 'Get';
}));
app.use(route.get('/api/items/:id', function*(id) {
    this.body = 'Get id: ' + id;
}));
app.use(route.post('/api/items', function*() {
    this.body = 'Post';
}));
app.use(route.put('/api/items/:id', function*(id) {
    this.body = 'Put id: ' + id;
}));
app.use(route.delete('/api/items/:id', function*(id) {
    this.body = 'Delete id: ' + id;
}));

// all other routes
app.use(function *() {
  this.body = 'Hello world';
});

var server = app.listen(3000, function() {
  console.log('Koa is listening to http://localhost:3000');
}); 

很明顯,Koa沒有能力減少像Express這樣的重複路線動詞。它還需要一個單獨的中間件來處理路由。我之所以選擇使用koa-route,是因爲它是由Koa團隊維護的,但是其他維護者可以使用很多路由。這些路線非常相似,快遞與使用相同的關鍵字爲他們的方法調用喜歡.get().put().post(),和.delete()。Koa處理路由的一個優勢是,它使用了ES6生成器函數,該函數有助於減少對回調的處理。

4.2.3哈皮

var Hapi = require('hapi');
var server = new Hapi.Server(3000);

server.route([
  {
    method: 'GET',
    path: '/api/items',
    handler: function(request, reply) {
      reply('Get item id');
    }
  },
  {
    method: 'GET',
    path: '/api/items/{id}',
    handler: function(request, reply) {
      reply('Get item id: ' + request.params.id);
    }
  },
  {
    method: 'POST',
    path: '/api/items',
    handler: function(request, reply) {
      reply('Post item');
    }
  },
  {
    method: 'PUT',
    path: '/api/items/{id}',
    handler: function(request, reply) {
      reply('Put item id: ' + request.params.id);
    }
  },
  {
    method: 'DELETE',
    path: '/api/items/{id}',
    handler: function(request, reply) {
      reply('Delete item id: ' + request.params.id);
    }
  },
  {
    method: 'GET',
    path: '/',
    handler: function(request, reply) {
      reply('Hello world');
    }
  }
]);

server.start(function() {
  console.log('Hapi is listening to http://localhost:3000');
});

Hapi中路由的第一印象是它們與其他框架相比具有多麼的清潔和可讀性。即使所需的選項methodpathhandler,和replay對路線很容易對眼睛。像Koa一樣,有大量的代碼重用,使錯誤的餘地更大。但是,這是有意的,Hapi更加關注配置,並希望代碼更整潔,以便在團隊中更輕鬆地使用。Hapi還希望改進錯誤處理,而無需在開發人員端編寫任何代碼。如果您嘗試查找未在REST API中描述的路由,它將返回一個帶有狀態代碼和錯誤描述的JSON對象。

 

5優劣勢

 

5.1快遞 Express

5.1.1好

Express不僅在這裏比較的三個框架中而且在Node.js的所有Web應用程序框架中都擁有最大的社區。它是三個框架中最成熟的框架,它擁有近5年的開發經驗,現在由StrongLoop來控制存儲庫。它提供了一種使服務器啓動並運行的簡單方法,並利用其內置的路由器促進了代碼重用。

5.1.2壞

Express中涉及許多手動繁瑣的任務。沒有內置的錯誤處理,很容易迷失在可以添加來解決解決方案的所有中間件中,並且有很多方法可以做一件事情。Express自稱是固執己見,這可能是好是壞,但對於必須選擇Express的新手開發人員來說,這是一件壞事。與其他框架相比,Express的足跡也更大。

 

5.2 Koa

5.2.1好

Koa佔用空間小,更具表現力,並且使中間件的編寫比其他框架容易得多。Koa基本上是一個準系統框架,開發人員可以在其中選擇(或編寫)他們要使用的中間件,而不會破壞Express或Hapi隨附的中間件。這是唯一包含ES6的框架,例如使用ES6生成器的框架。

5.2.2不好

Koa仍然不穩定並且正在大量開發中。使用ES6仍然領先於遊戲,例如需要使用Node.js的0.11.9+版本來運行Koa,現在Node.js上的最新穩定版本爲0.10.33。選擇Express或編寫自己的中間件是一件好事,但也有可能像Express一樣壞事。例如我們之前看過的路由器,有很多中間件路由器可以處理各種選項。

 

5.3哈皮 Hapi

5.3.1好

Hapi自豪地說他們的框架基於代碼之上的配置,許多開發人員會認爲這是一件好事。這在大型團隊中很常見,以增加一致性和可重用性。此外,在沃爾瑪實驗室以及許多其他在生產中使用Hapi的知名公司支持該框架的情況下,該框架已經進行了實戰測試,公司有足夠的信心從中運行其應用程序。因此,種種跡象表明,該項目將繼續發展成爲一個很好的框架。

5.3.2壞

Hapi顯然似乎更適合於更大或更復雜的應用程序。放在一起一個簡單的Web應用程序可能需要太多樣板代碼,並且使用hapi的示例或開源應用程序也很多。因此,選擇它可能會涉及開發人員更多的部分,而不是使用第三方中間件。

 

6小結

我們已經看到了所有這三個框架的一些不錯但實用的示例。Express絕對是這三個框架中最受歡迎和最受認可的框架。在應用程序上開始新開發時,首先使用Express創建服務器幾乎是一種反應,但希望現在可能會涉及到一些考慮是否使用Koa或Hapi作爲替代方案。Koa展現了對未來的真正希望,並且在擁抱ES6和Web開發社區正在邁向的Web組件思想方面遙遙領先。Hapi應該是大型團隊和大型項目的首要考慮因素。它推動通過代碼進行配置,這幾乎總是使團隊受益,並且大多數團隊都在努力實現可重用性。現在,出去嘗試一個新的框架,也許您會喜歡它,也許您會討厭,但是您永遠不會知道,最後,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章