如果您是Node.js开发人员,则有时可能会使用Express.js创建您的应用程序或API。Express.js是一个非常流行的Node.js框架,甚至在它之上构建了其他一些框架,例如Sails.js , kraken.js , KeystoneJS 等 。然而,在这种流行中,JavaScript框架(例如Koa和hapi)也引起了JavaScript界的关注。
在本文中,我们将研究Express.js,Koa和hapi.js —它们的相似之处,不同之处和用例。
背景
首先让我们分别介绍这些框架。
Express.js
Express.js被描述为Node.js的标准服务器框架。 它由TJ Holowaychuk创建,于被StrongLoop收购,目前由Node.js Foundation孵化器维护。 去年 ,它的下载量约为170+百万次,毫无疑问,它是最受欢迎的Node.js框架。
柯阿
Express的同一个人于底开始在Koa上进行开发。 这就是Express的未来。 Koa还被描述为Express框架的一种更加现代,模块化和简约的版本。
Hapi.js
Hapi.js是由Walmart Labs的团队(由Eran Hammer领导)在尝试Express并发现它无法满足他们的要求后开发的。 它最初是在Express之上开发的,但随着时间的流逝,它发展成为一个成熟的框架。
有趣的事实:hapi是Http API服务器的缩写。
哲学
现在我们对框架及其创建背景有了一定的了解,让我们根据重要的概念(例如其理念,路由等)对每个框架进行比较。
注意:所有代码示例都在ES6中,并使用Express.js的版本4,Koa的2.4和hapi.js的17。
Express.js
Express被构建为一个简单,不受质疑的Web框架。 从其GitHub README :
Express的理念是为HTTP服务器提供小型,健壮的工具,使其成为单页应用程序,网站,混合或公共HTTP API的理想解决方案。
Express.js很小,并且没有许多现成的功能。 它不会强制执行文件结构,ORM或模板引擎之类的操作。
柯阿
尽管Express.js很小,但Koa可以拥有更简单的代码,大约2k LOC。 其目的是让开发人员更具表现力。 与Express.js一样,可以使用现有或自定义插件和中间件轻松对其进行扩展。 它的方法更具未来性,因为它严重依赖于相对较新的JavaScript功能,例如generators和async / await 。
Hapi.js
与Koa和Express.js相比,Hapi.js更加注重配置并提供了更多现成的功能。 hapi的创建者之一Eran Hammer在他的博客文章中描述了正确构建框架的原因:
创建hapi的想法是,配置优于代码,必须将业务逻辑与传输层隔离,并且应将诸如缓冲区和流之类的本机节点结构作为第一类对象来支持。
启动服务器
启动服务器是我们在项目中需要做的基本工作之一。 让我们研究一下如何在不同的框架中完成它。 在每个示例中,我们将启动服务器并侦听端口3000。
Express.js
const express = require('express');const app = express();app.listen(3000, () => console.log('App is listening on port 3000!'));
在Express.js中启动服务器非常简单,就像需要express
程序包一样,将express
应用程序初始化为app
变量,然后调用app.listen()
方法,该方法只是本地Node.js http.createServer()的包装。方法。
柯阿
在Koa中启动服务器与Express.js非常相似:
const Koa = require('koa');const app = new Koa();app.listen(3000, () => console.log('App is listening on port 3000!'));
所述app.listen()
在兴亚方法也是围绕的包装http.createServer()
方法。
Hapi.js
在hapi.js中启动服务器与我们许多人习惯于Express完全不同:
const Hapi = require('hapi');const server = Hapi.server({host: 'localhost',port: 3000});async function start() {try {await server.start();}catch (err) {console.log(err);process.exit(1);}console.log('Server running at:', server.info.uri);};start();
在上面的代码块中,首先我们需要hapi
包,然后使用Hapi.server()
实例化服务器,该服务器具有一个包含主机和端口参数的单个配置对象参数。 然后,我们使用异步server.start()
函数启动服务器。
与Express.js和Koa不同,hapi中的server.start()
函数不是本机http.createServer()
方法的包装。 相反,它实现了自己的自定义逻辑。
上面的代码示例来自hapi.js网站,并显示了hapi.js的创建者对配置和错误处理的重视。
路由
路由是现代Web应用程序的另一个关键方面。 让我们为每个框架中的简单Hello World应用程序定义一个/hello
路由,以了解路由对其的工作方式。
Express.js
app.get('/hello', (req, res) => res.send('Hello World!'));
在Express中创建路由就像使用所需的HTTP方法调用app
对象一样简单。 语法为app.METHOD(PATH, HANDLER)
,其中PATH是服务器上的路径,而HANDLER是匹配路径时调用的函数。
柯阿
Koa没有捆绑自己的路由器,因此我们必须使用路由器中间件来处理Koa应用程序上的路由。 两种常见的路由选项是koa-route和koa-router 。 这是使用koa-route的示例:
const route = require('koa-route');app.use(route.get('/hello', ctx => {ctx.body = 'Hello World!';}));
我们可以立即看到Koa需要将每个路由定义为应用程序上的中间件。ctx
是一个上下文对象,包含Node的request
和response
对象。ctx.body
是response
对象中的方法,可用于将响应主体设置为string
,Buffer
,Stream
,Object
或null
。 route方法的第二个参数可以是异步或生成器函数,因此减少了回调的使用。
Hapi.js
server.route({method: 'GET',path:'/hello',handler: function (request, h) {return 'Hello world!';}});
hapi中的server.route()
方法采用一个带有以下参数的配置对象:method
,path
和handler
。 您可以在此处查看有关在hapi中进行路由的文档。
处理函数中的request
参数是一个对象,其中包含用户的请求详细信息,而h
参数则描述为响应工具包。
中间件
节点开发人员惯用的主要概念之一是使用中间件。中间件功能是位于请求和响应之间的功能。 他们可以访问request
和response
对象,并且可以在处理完之后运行下一个中间件。 让我们看一下如何通过实现一个简单的函数来记录它们在不同框架中的定义,该函数记录向服务器发出请求的时间。
Express.js
app.use((req, res, next) => {console.log(`Time: ${Date.now()}`);next();})
在Express.js中注册中间件就像通过使用app.use()
函数将中间件绑定到app对象一样简单。 您可以在Express.js中阅读有关中间件的更多信息 。
柯阿
app.use(async (ctx, next) => {console.log(`Time: ${Date.now()}`);await next();});
Koa中的中间件注册类似于Express.js。 主要区别在于, 上下文对象 (ctx
)代替了Express.js中的request
和response
对象,而Koa包含了用于定义中间件功能的现代async / await范例。
Hapi.js
server.ext('onRequest', (request, h) => {console.log(`Time: ${Date.now()}`);return h.continue;});
在hapi.js中, 请求生命周期中有某些扩展点。server.ext()
方法注册在请求生命周期中某个点要调用的扩展函数。 您可以在此处了解更多信息。 我们在上面的示例中使用onRequest
扩展点来注册中间件(或扩展)功能。
用法
从上面的比较和代码示例中可以明显看出,Express和Koa最相似,而hapi.js是背离Node.js开发人员所习惯的框架。 因此,在尝试构建快速便捷的应用程序时,hapi.js可能不是最佳选择,因为要花一些时间才能习惯。
我认为,在构建中小型应用程序时,Express仍然是一个不错的选择。 对于非常大型的应用程序,它的管理可能会变得有些复杂,因为它不具备hapi.js内置的模块化功能,并支持自定义插件及其独特的路由方法 。 但是,最近有一些关于Express.js未来的猜测, 因为TJ宣布他不再从事此工作,并且降低了发布更新的速度 。 有点稳定,不会很快消失。 它还有大量的开发人员为其构建各种扩展程序和插件。
与Express.js一样,Koa非常适合许多简单的Node.js项目。 它仅包含最低要求(内置零中间件),并鼓励开发人员通过构建或使用可用的外部中间件向其添加所需的东西。 它充分利用了现代的JavaScript生成器功能并大量进行了异步/等待,这使其方法具有一定的未来性。 它的中间件级联模式也很棒,因为它使在应用程序中实现和理解中间件流变得非常容易。 如果您尚未准备好接受发生器功能之类的新事物,或者您不愿意花时间构建所需的所有中间件,那么Koa可能不是您的理想选择。 社区对Koa的支持正在迅速增长,因为它已经为它构建了大量的外部中间件(有些是Koa核心团队提供的),用于路由,日志记录等常见任务。
如果您和您的团队比实际编码功能花费更多的时间进行配置,那么Hapi.js是绝对的选择。 它构建为模块化的,可用于具有大型团队的大型应用程序。 它鼓励微服务架构,因为您的应用程序的各个部分可以作为插件构建并在启动之前在服务器中注册。 Hapi.js由诸如Auth0和Lob之类的大公司提供支持,因此它有一个非常美好的未来,并且不会很快消失。 某些知名人士也信任它,如在其社区页面上所示 。
与Koa和Express.js相比,Hapi.js具有更多现成的功能,例如对身份验证,缓存,日志记录,验证等的支持,这使它看起来更像一个成熟的框架。 您可以查看他们的教程页面,以更好地了解他们提供的功能。 针对hapi.js构建并没有太多开源项目和插件,因此如果开发人员计划扩展其核心功能,则使用它们的开发人员可能需要完成许多工作。
结论
在启动新项目时,这三个框架都是不错的选择,但最终您的选择将取决于项目需求,团队成员以及您正在寻找的灵活性水平。
From: /express-koa-hapi/